Hide non-manga entries in search on Madara sources (#11304)
* Hide non-manga entries in search on Madara sources. * Remove deleted method in overrides. * Remove unused methods and fix final modifier warning. * Remove commented lines in NS. * Remove hardcoded selector in old sources.
This commit is contained in:
parent
6b3a52ddd7
commit
aa9e858dc2
|
@ -17,41 +17,4 @@ class CafeComYaoi : Madara(
|
||||||
override val client: OkHttpClient = super.client.newBuilder()
|
override val client: OkHttpClient = super.client.newBuilder()
|
||||||
.addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
|
.addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// [...document.querySelectorAll('input[name="genre[]"]')]
|
|
||||||
// .map(x => `Genre("${document.querySelector('label[for=' + x.id + ']').innerHTML.trim()}", "${x.value}")`)
|
|
||||||
// .join(',\n')
|
|
||||||
override fun getGenreList(): List<Genre> = listOf(
|
|
||||||
Genre("Ação", "acao"),
|
|
||||||
Genre("Aventura", "aventura"),
|
|
||||||
Genre("BDSM", "bdsm"),
|
|
||||||
Genre("BL", "bl"),
|
|
||||||
Genre("Comédia", "comedia"),
|
|
||||||
Genre("Doujinshi", "doujinshi"),
|
|
||||||
Genre("Drama", "drama"),
|
|
||||||
Genre("Fantasia", "fantasia"),
|
|
||||||
Genre("Gender Bender", "gender-bender"),
|
|
||||||
Genre("Harem", "harem"),
|
|
||||||
Genre("Histórico", "historico"),
|
|
||||||
Genre("Horror", "horror"),
|
|
||||||
Genre("Máfia", "mafia"),
|
|
||||||
Genre("Mangá", "manga"),
|
|
||||||
Genre("Manhua", "manhua"),
|
|
||||||
Genre("Manhwa", "manhwa"),
|
|
||||||
Genre("Mature", "mature"),
|
|
||||||
Genre("Mistério", "misterio"),
|
|
||||||
Genre("Omegaverse", "omegaverse"),
|
|
||||||
Genre("One shot", "one-shot"),
|
|
||||||
Genre("Psicológico", "psicologico"),
|
|
||||||
Genre("Romance", "romance"),
|
|
||||||
Genre("School Life", "school-life"),
|
|
||||||
Genre("Sci-fi", "sci-fi"),
|
|
||||||
Genre("Shoujo", "shoujo"),
|
|
||||||
Genre("Slice of Life", "slice-of-life"),
|
|
||||||
Genre("Smut", "smut"),
|
|
||||||
Genre("Sobrenatural", "sobrenatural"),
|
|
||||||
Genre("Tragédia", "tragedia"),
|
|
||||||
Genre("Triângulo Amoroso", "triangulo-amoroso"),
|
|
||||||
Genre("Webcomic", "webcomic")
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,16 @@ import org.jsoup.nodes.Element
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class DoujinHentai : Madara("DoujinHentai", "https://doujinhentai.net", "es", SimpleDateFormat("d MMM. yyyy", Locale.ENGLISH)) {
|
class DoujinHentai : Madara(
|
||||||
|
"DoujinHentai",
|
||||||
|
"https://doujinhentai.net",
|
||||||
|
"es",
|
||||||
|
SimpleDateFormat("d MMM. yyyy", Locale.ENGLISH),
|
||||||
|
fetchGenresOnInit = false
|
||||||
|
) {
|
||||||
|
|
||||||
|
override val useLoadMoreSearch = false
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/lista-manga-hentai?orderby=views&page=$page", headers)
|
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/lista-manga-hentai?orderby=views&page=$page", headers)
|
||||||
override fun popularMangaSelector() = "div.col-md-3 a"
|
override fun popularMangaSelector() = "div.col-md-3 a"
|
||||||
override fun popularMangaFromElement(element: Element): SManga {
|
override fun popularMangaFromElement(element: Element): SManga {
|
||||||
|
|
|
@ -13,11 +13,11 @@ class EGYManga : Madara(
|
||||||
SimpleDateFormat("MMMM dd, yyyy", Locale("ar"))
|
SimpleDateFormat("MMMM dd, yyyy", Locale("ar"))
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override val pageListParseSelector = "div.separator"
|
// The website does not flag the content.
|
||||||
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
override val pageListParseSelector = "div.separator"
|
||||||
override fun popularMangaSelector() =
|
|
||||||
"div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> =
|
override fun chapterListParse(response: Response): List<SChapter> =
|
||||||
super.chapterListParse(response).reversed()
|
super.chapterListParse(response).reversed()
|
||||||
|
|
|
@ -6,6 +6,16 @@ import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class GeceninLordu : Madara("Gecenin Lordu", "https://geceninlordu.com/", "tr", SimpleDateFormat("dd MMM yyyy", Locale("tr"))) {
|
class GeceninLordu : Madara(
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/?s=$query&post_type=wp-manga")
|
"Gecenin Lordu",
|
||||||
|
"https://geceninlordu.com/",
|
||||||
|
"tr",
|
||||||
|
SimpleDateFormat("dd MMM yyyy", Locale("tr")),
|
||||||
|
fetchGenresOnInit = false
|
||||||
|
) {
|
||||||
|
|
||||||
|
override val useLoadMoreSearch = false
|
||||||
|
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
|
||||||
|
GET("$baseUrl/?s=$query&post_type=wp-manga")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
class Gemanga : Madara("Gemanga", "https://gemanga.com", "ar") {
|
class Gemanga : Madara("Gemanga", "https://gemanga.com", "ar") {
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ class HentaiManga : Madara(
|
||||||
dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.US)
|
dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.US)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
class HentaiWebtoon : Madara("HentaiWebtoon", "https://hentaiwebtoon.com", "en") {
|
class HentaiWebtoon : Madara("HentaiWebtoon", "https://hentaiwebtoon.com", "en") {
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,12 @@ class InstaManhwa : Madara(
|
||||||
"InstaManhwa",
|
"InstaManhwa",
|
||||||
"https://www.instamanhwa.com",
|
"https://www.instamanhwa.com",
|
||||||
"en",
|
"en",
|
||||||
SimpleDateFormat("dd MMMM, yyyy", Locale.US)
|
SimpleDateFormat("dd MMMM, yyyy", Locale.US),
|
||||||
|
fetchGenresOnInit = false
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override val supportsLatest: Boolean = false
|
override val supportsLatest: Boolean = false
|
||||||
|
override val useLoadMoreSearch = false
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/latest?page=$page", headers)
|
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/latest?page=$page", headers)
|
||||||
|
|
||||||
|
@ -57,9 +60,6 @@ class InstaManhwa : Madara(
|
||||||
return client.newCall(POST("$baseUrl/ajax", headers, body)).execute().asJsoup()
|
return client.newCall(POST("$baseUrl/ajax", headers, body)).execute().asJsoup()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not used
|
|
||||||
override fun getGenreList(): List<Genre> = emptyList()
|
|
||||||
|
|
||||||
// Not used
|
// Not used
|
||||||
override fun getFilterList(): FilterList = FilterList()
|
override fun getFilterList(): FilterList = FilterList()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
class MangaGreat : Madara("MangaGreat", "https://mangagreat.com", "en") {
|
class MangaGreat : Madara("MangaGreat", "https://mangagreat.com", "en") {
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,9 @@ import okhttp3.Response
|
||||||
|
|
||||||
class ManhuaES : Madara("Manhua ES", "https://manhuaes.com", "en") {
|
class ManhuaES : Madara("Manhua ES", "https://manhuaes.com", "en") {
|
||||||
|
|
||||||
// The website is incorrectly flagging a lot of their
|
// The website does not flag the content.
|
||||||
// manga content as video and text instead. To bypass this, we
|
override val useLoadMoreSearch = false
|
||||||
// use the old selector that includes all.
|
override val filterNonMangaItems = false
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
var chapterList = super.chapterListParse(response)
|
var chapterList = super.chapterListParse(response)
|
||||||
|
|
|
@ -4,10 +4,9 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
class ManhuaPlus : Madara("Manhua Plus", "https://manhuaplus.com", "en") {
|
class ManhuaPlus : Madara("Manhua Plus", "https://manhuaplus.com", "en") {
|
||||||
|
|
||||||
// The website is incorrectly flagging a lot of their
|
// The website does not flag the content.
|
||||||
// manga content as video instead. To bypass this, we
|
override val useLoadMoreSearch = false
|
||||||
// use the old selector that includes all.
|
override val filterNonMangaItems = false
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
|
||||||
|
|
||||||
override val pageListParseSelector = ".read-container img"
|
override val pageListParseSelector = ".read-container img"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.extension.en.manhuaus
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
class ManhuaUS : Madara("ManhuaUS", "https://manhuaus.com", "en") {
|
class ManhuaUS : Madara("ManhuaUS", "https://manhuaus.com", "en") {
|
||||||
|
|
||||||
override val useNewChapterEndpoint: Boolean = true
|
override val useNewChapterEndpoint: Boolean = true
|
||||||
|
|
||||||
// The website is incorrectly flagging a lot of their
|
// The website does not flag the content.
|
||||||
// manga content as text instead. To bypass this, we
|
override val useLoadMoreSearch = false
|
||||||
// use the old selector that includes all.
|
override val filterNonMangaItems = false
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,9 @@ abstract class Manhwa18Cc(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val baseUrl: String,
|
override val baseUrl: String,
|
||||||
lang: String
|
lang: String
|
||||||
) : Madara(name, baseUrl, lang) {
|
) : Madara(name, baseUrl, lang, fetchGenresOnInit = false) {
|
||||||
|
|
||||||
|
override val useLoadMoreSearch = false
|
||||||
|
|
||||||
override fun popularMangaSelector() = "div.manga-item"
|
override fun popularMangaSelector() = "div.manga-item"
|
||||||
override val popularMangaUrlSelector = "div.data > h3 > a"
|
override val popularMangaUrlSelector = "div.data > h3 > a"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
class Manhwa18Org : Madara("Manhwa18.org", "https://manhwa18.org", "en") {
|
class Manhwa18Org : Madara("Manhwa18.org", "https://manhwa18.org", "en") {
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ class Manhwa68 : Madara(
|
||||||
dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.US)
|
dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.US)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
class Manhwatop : Madara("Manhwatop", "https://manhwatop.com", "en") {
|
class Manhwatop : Madara("Manhwatop", "https://manhwatop.com", "en") {
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ class ManyToonMe : Madara("ManyToon.me", "https://manytoon.me", "en") {
|
||||||
|
|
||||||
override val useNewChapterEndpoint: Boolean = true
|
override val useNewChapterEndpoint: Boolean = true
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,11 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservable
|
import eu.kanade.tachiyomi.network.asObservable
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
@ -32,7 +29,7 @@ class NeoxScanlator :
|
||||||
"Neox Scanlator",
|
"Neox Scanlator",
|
||||||
DEFAULT_BASE_URL,
|
DEFAULT_BASE_URL,
|
||||||
"pt-BR",
|
"pt-BR",
|
||||||
SimpleDateFormat("MMMMM dd, yyyy", Locale("pt", "BR"))
|
SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR"))
|
||||||
),
|
),
|
||||||
ConfigurableSource {
|
ConfigurableSource {
|
||||||
|
|
||||||
|
@ -57,13 +54,6 @@ class NeoxScanlator :
|
||||||
.add("Accept-Language", ACCEPT_LANGUAGE)
|
.add("Accept-Language", ACCEPT_LANGUAGE)
|
||||||
.add("Referer", REFERER)
|
.add("Referer", REFERER)
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
|
||||||
val mangaPage = super.searchMangaParse(response)
|
|
||||||
val filteredResult = mangaPage.mangas.filter { it.title.contains(NOVEL_REGEX).not() }
|
|
||||||
|
|
||||||
return MangasPage(filteredResult, mangaPage.hasNextPage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sometimes the site changes the manga URL. This override will
|
// Sometimes the site changes the manga URL. This override will
|
||||||
// add an error instead of the HTTP 404 to inform the user to
|
// add an error instead of the HTTP 404 to inform the user to
|
||||||
// migrate from Neox to Neox to update the URL.
|
// migrate from Neox to Neox to update the URL.
|
||||||
|
@ -90,9 +80,6 @@ class NeoxScanlator :
|
||||||
return GET(page.imageUrl!!, newHeaders)
|
return GET(page.imageUrl!!, newHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only status and order by filter work.
|
|
||||||
override fun getFilterList(): FilterList = FilterList(super.getFilterList().slice(3..4))
|
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
val baseUrlPref = EditTextPreference(screen.context).apply {
|
val baseUrlPref = EditTextPreference(screen.context).apply {
|
||||||
key = BASE_URL_PREF_KEY
|
key = BASE_URL_PREF_KEY
|
||||||
|
@ -136,7 +123,5 @@ class NeoxScanlator :
|
||||||
"extensão, esta configuração será apagada."
|
"extensão, esta configuração será apagada."
|
||||||
|
|
||||||
private const val RESTART_TACHIYOMI = "Reinicie o Tachiyomi para aplicar as configurações."
|
private const val RESTART_TACHIYOMI = "Reinicie o Tachiyomi para aplicar as configurações."
|
||||||
|
|
||||||
private val NOVEL_REGEX = "novel|livro".toRegex(RegexOption.IGNORE_CASE)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,17 @@ import okhttp3.Request
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class PojokManga : Madara("Pojok Manga", "https://pojokmanga.com", "id", SimpleDateFormat("MMM dd, yyyy", Locale.US)) {
|
class PojokManga : Madara(
|
||||||
|
"Pojok Manga",
|
||||||
|
"https://pojokmanga.com",
|
||||||
|
"id",
|
||||||
|
SimpleDateFormat("MMM dd, yyyy", Locale.US)
|
||||||
|
) {
|
||||||
|
|
||||||
|
override val useLoadMoreSearch = false
|
||||||
|
|
||||||
|
override val useNewChapterEndpoint = true
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
var url = "$baseUrl/${searchPage(page)}".toHttpUrlOrNull()!!.newBuilder()
|
var url = "$baseUrl/${searchPage(page)}".toHttpUrlOrNull()!!.newBuilder()
|
||||||
url.addQueryParameter("s", query)
|
url.addQueryParameter("s", query)
|
||||||
|
@ -76,22 +86,16 @@ class PojokManga : Madara("Pojok Manga", "https://pojokmanga.com", "id", SimpleD
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
override fun getFilterList(): FilterList {
|
||||||
AuthorFilter(authorFilterTitle),
|
val filters = super.getFilterList().toMutableList()
|
||||||
ArtistFilter(artistFilterTitle),
|
|
||||||
YearFilter(yearFilterTitle),
|
|
||||||
StatusFilter(statusFilterTitle, getStatusList()),
|
|
||||||
OrderByFilter(orderByFilterTitle, orderByFilterOptions.zip(orderByFilterOptionsValues)),
|
|
||||||
AdultContentFilter(adultContentFilterTitle, adultContentFilterOptions),
|
|
||||||
Filter.Separator(),
|
|
||||||
Filter.Header(genreFilterHeader),
|
|
||||||
GenreConditionFilter(genreConditionFilterTitle, genreConditionFilterOptions),
|
|
||||||
GenreList(genreFilterTitle, getGenreList()),
|
|
||||||
Filter.Separator(),
|
|
||||||
Filter.Header("NOTE: cant be used with other filter!"),
|
|
||||||
Filter.Header("$name Project List page"),
|
|
||||||
ProjectFilter(),
|
|
||||||
)
|
|
||||||
|
|
||||||
override val useNewChapterEndpoint = true
|
filters += listOf(
|
||||||
|
Filter.Separator(),
|
||||||
|
Filter.Header("NOTE: cant be used with other filter!"),
|
||||||
|
Filter.Header("$name Project List page"),
|
||||||
|
ProjectFilter()
|
||||||
|
)
|
||||||
|
|
||||||
|
return FilterList(filters)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ class ShieldManga : Madara("Shield Manga", "https://shieldmanga.io", "en") {
|
||||||
.addNetworkInterceptor(rateLimitInterceptor)
|
.addNetworkInterceptor(rateLimitInterceptor)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() =
|
override val useLoadMoreSearch = false
|
||||||
"div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val filterNonMangaItems = false
|
||||||
|
|
||||||
override fun chapterListSelector() = "li.wp-manga-hapter, .version-chap li"
|
override fun chapterListSelector() = "li.wp-manga-hapter, .version-chap li"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
class Zinmanga : Madara("Zinmanga", "https://zinmanga.com", "en") {
|
class Zinmanga : Madara("Zinmanga", "https://zinmanga.com", "en") {
|
||||||
|
|
||||||
// The website does not flag the content, so we just use the old selector.
|
// The website does not flag the content.
|
||||||
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
override val useLoadMoreSearch = false
|
||||||
|
override val filterNonMangaItems = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ import okhttp3.Response
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
import rx.Single
|
||||||
|
import rx.schedulers.Schedulers
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -37,7 +39,8 @@ abstract class Madara(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val baseUrl: String,
|
override val baseUrl: String,
|
||||||
final override val lang: String,
|
final override val lang: String,
|
||||||
private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US)
|
private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US),
|
||||||
|
protected val fetchGenresOnInit: Boolean = true
|
||||||
) : ParsedHttpSource() {
|
) : ParsedHttpSource() {
|
||||||
|
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
@ -52,6 +55,12 @@ abstract class Madara(
|
||||||
|
|
||||||
protected open val json: Json by injectLazy()
|
protected open val json: Json by injectLazy()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If enabled, will remove non-manga items in search.
|
||||||
|
* Can be disabled if the source incorrectly sets the entry types.
|
||||||
|
*/
|
||||||
|
protected open val filterNonMangaItems = true
|
||||||
|
|
||||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||||
.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/78.0$userAgentRandomizer")
|
.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/78.0$userAgentRandomizer")
|
||||||
.add("Referer", baseUrl)
|
.add("Referer", baseUrl)
|
||||||
|
@ -59,7 +68,7 @@ abstract class Madara(
|
||||||
// Popular Manga
|
// Popular Manga
|
||||||
|
|
||||||
// exclude/filter bilibili manga from list
|
// exclude/filter bilibili manga from list
|
||||||
override fun popularMangaSelector() = "div.page-item-detail.manga:not(:has(a[href*='bilibilicomics.com']))"
|
override fun popularMangaSelector() = "div.page-item-detail:not(:has(a[href*='bilibilicomics.com']))"
|
||||||
|
|
||||||
open val popularMangaUrlSelector = "div.post-title a"
|
open val popularMangaUrlSelector = "div.post-title a"
|
||||||
|
|
||||||
|
@ -93,12 +102,22 @@ abstract class Madara(
|
||||||
add("vars[order]", "desc")
|
add("vars[order]", "desc")
|
||||||
add("vars[sidebar]", if (popular) "full" else "right")
|
add("vars[sidebar]", if (popular) "full" else "right")
|
||||||
add("vars[manga_archives_item_layout]", "big_thumbnail")
|
add("vars[manga_archives_item_layout]", "big_thumbnail")
|
||||||
|
|
||||||
|
if (filterNonMangaItems) {
|
||||||
|
add("vars[meta_query][0][key]", "_wp_manga_chapter_type")
|
||||||
|
add("vars[meta_query][0][value]", "manga")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open val formHeaders: Headers by lazy { headersBuilder().build() }
|
open val formHeaders: Headers by lazy { headersBuilder().build() }
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
return POST("$baseUrl/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, true).build(), CacheControl.FORCE_NETWORK)
|
return POST(
|
||||||
|
"$baseUrl/wp-admin/admin-ajax.php",
|
||||||
|
formHeaders,
|
||||||
|
formBuilder(page, true).build(),
|
||||||
|
CacheControl.FORCE_NETWORK
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaNextPageSelector(): String? = "body:not(:has(.no-posts))"
|
override fun popularMangaNextPageSelector(): String? = "body:not(:has(.no-posts))"
|
||||||
|
@ -124,18 +143,37 @@ abstract class Madara(
|
||||||
return MangasPage(mangas, mp.hasNextPage)
|
return MangasPage(mangas, mp.hasNextPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
|
||||||
if (genresList == null)
|
|
||||||
genresList = parseGenres(client.newCall(searchMangaRequest(1, "genre", getFilterList())).execute().asJsoup())
|
|
||||||
return super.popularMangaParse(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search Manga
|
// Search Manga
|
||||||
|
|
||||||
open val mangaSubString = "manga"
|
open val mangaSubString = "manga"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If enabled, the search will use the madara_load_more action instead of
|
||||||
|
* the normal page. This allows more control over the query and will permit
|
||||||
|
* the filtering of non-manga items such as novels or videos.
|
||||||
|
*/
|
||||||
|
open val useLoadMoreSearch = true
|
||||||
|
|
||||||
|
open fun searchFormBuilder(showOnlyManga: Boolean): FormBody.Builder = FormBody.Builder().apply {
|
||||||
|
add("action", "madara_load_more")
|
||||||
|
add("page", "0")
|
||||||
|
add("template", "madara-core/content/content-search")
|
||||||
|
add("vars[paged]", "1")
|
||||||
|
add("vars[template]", "archive")
|
||||||
|
add("vars[sidebar]", "right")
|
||||||
|
add("vars[post_type]", "wp-manga")
|
||||||
|
add("vars[post_status]", "publish")
|
||||||
|
add("vars[manga_archives_item_layout]", "big_thumbnail")
|
||||||
|
add("vars[post_per_page]", "20")
|
||||||
|
|
||||||
|
if (filterNonMangaItems && showOnlyManga) {
|
||||||
|
add("vars[meta_query][0][key]", "_wp_manga_chapter_type")
|
||||||
|
add("vars[meta_query][0][value]", "manga")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
||||||
if (query.startsWith(URL_SEARCH_PREFIX)) {
|
if (query.startsWith(URL_SEARCH_PREFIX) && !useLoadMoreSearch) {
|
||||||
val mangaUrl = "$baseUrl/$mangaSubString/${query.substringAfter(URL_SEARCH_PREFIX)}"
|
val mangaUrl = "$baseUrl/$mangaSubString/${query.substringAfter(URL_SEARCH_PREFIX)}"
|
||||||
return client.newCall(GET(mangaUrl, headers))
|
return client.newCall(GET(mangaUrl, headers))
|
||||||
.asObservable().map { response ->
|
.asObservable().map { response ->
|
||||||
|
@ -157,21 +195,25 @@ abstract class Madara(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
protected open fun parseGenres(document: Document): List<Genre> {
|
||||||
if (genresList == null)
|
return document.selectFirst("div.checkbox-group")
|
||||||
genresList = parseGenres(response.asJsoup(response.peekBody(Long.MAX_VALUE).string()))
|
?.select("div.checkbox")
|
||||||
return super.searchMangaParse(response)
|
.orEmpty()
|
||||||
}
|
.map { li ->
|
||||||
|
Genre(
|
||||||
private fun parseGenres(document: Document): List<Genre>? {
|
li.selectFirst("label").text(),
|
||||||
return document.selectFirst("div.checkbox-group")?.select("div.checkbox")?.map { li ->
|
li.selectFirst("input[type=checkbox]").`val`()
|
||||||
Genre(li.selectFirst("label").text(), li.selectFirst("input[type=checkbox]").`val`())
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun searchPage(page: Int): String = "page/$page/"
|
protected open fun searchPage(page: Int): String = "page/$page/"
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
if (useLoadMoreSearch) {
|
||||||
|
return searchLoadMoreRequest(page, query, filters)
|
||||||
|
}
|
||||||
|
|
||||||
val url = "$baseUrl/${searchPage(page)}".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/${searchPage(page)}".toHttpUrlOrNull()!!.newBuilder()
|
||||||
url.addQueryParameter("s", query)
|
url.addQueryParameter("s", query)
|
||||||
url.addQueryParameter("post_type", "wp-manga")
|
url.addQueryParameter("post_type", "wp-manga")
|
||||||
|
@ -222,6 +264,147 @@ abstract class Madara(
|
||||||
return GET(url.toString(), headers)
|
return GET(url.toString(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun searchLoadMoreRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
val showOnlyManga = filters.filterIsInstance<ShowOnlyMangaFilter>()
|
||||||
|
.firstOrNull()?.state ?: true
|
||||||
|
|
||||||
|
val formBodyBuilder = searchFormBuilder(showOnlyManga).apply {
|
||||||
|
if (query.startsWith(URL_SEARCH_PREFIX)) {
|
||||||
|
add("vars[name]", query.removePrefix(URL_SEARCH_PREFIX))
|
||||||
|
|
||||||
|
return@apply
|
||||||
|
}
|
||||||
|
|
||||||
|
add("vars[s]", query)
|
||||||
|
|
||||||
|
var metaQueryIdx = if (filterNonMangaItems && showOnlyManga) 1 else 0
|
||||||
|
var taxQueryIdx = 0
|
||||||
|
val genres = filters.filterIsInstance<GenreList>().firstOrNull()?.state
|
||||||
|
?.filter { it.state }
|
||||||
|
?.map { it.id }
|
||||||
|
.orEmpty()
|
||||||
|
|
||||||
|
filters.forEach { filter ->
|
||||||
|
when (filter) {
|
||||||
|
is AuthorFilter -> {
|
||||||
|
if (filter.state.isNotBlank()) {
|
||||||
|
add("vars[tax_query][$taxQueryIdx][taxonomy]", "wp-manga-author")
|
||||||
|
add("vars[tax_query][$taxQueryIdx][field]", "name")
|
||||||
|
add("vars[tax_query][$taxQueryIdx][terms]", filter.state)
|
||||||
|
|
||||||
|
taxQueryIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is ArtistFilter -> {
|
||||||
|
if (filter.state.isNotBlank()) {
|
||||||
|
add("vars[tax_query][$taxQueryIdx][taxonomy]", "wp-manga-artist")
|
||||||
|
add("vars[tax_query][$taxQueryIdx][field]", "name")
|
||||||
|
add("vars[tax_query][$taxQueryIdx][terms]", filter.state)
|
||||||
|
|
||||||
|
taxQueryIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is YearFilter -> {
|
||||||
|
if (filter.state.isNotBlank()) {
|
||||||
|
add("vars[tax_query][$taxQueryIdx][taxonomy]", "wp-manga-release")
|
||||||
|
add("vars[tax_query][$taxQueryIdx][field]", "name")
|
||||||
|
add("vars[tax_query][$taxQueryIdx][terms]", filter.state)
|
||||||
|
|
||||||
|
taxQueryIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is StatusFilter -> {
|
||||||
|
val statuses = filter.state
|
||||||
|
.filter { it.state }
|
||||||
|
.map { it.id }
|
||||||
|
|
||||||
|
if (statuses.isNotEmpty()) {
|
||||||
|
add("vars[meta_query][$metaQueryIdx][key]", "_wp_manga_status")
|
||||||
|
|
||||||
|
statuses.forEachIndexed { i, slug ->
|
||||||
|
add("vars[meta_query][$metaQueryIdx][value][$i]", slug)
|
||||||
|
}
|
||||||
|
|
||||||
|
metaQueryIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is OrderByFilter -> {
|
||||||
|
if (filter.state != 0) {
|
||||||
|
when (filter.toUriPart()) {
|
||||||
|
"latest" -> {
|
||||||
|
add("vars[orderby]", "meta_value_num")
|
||||||
|
add("vars[order]", "DESC")
|
||||||
|
add("vars[meta_key]", "_latest_update")
|
||||||
|
}
|
||||||
|
"alphabet" -> {
|
||||||
|
add("vars[orderby]", "post_title")
|
||||||
|
add("vars[order]", "ASC")
|
||||||
|
}
|
||||||
|
"rating" -> {
|
||||||
|
add("vars[orderby][query_average_reviews]", "DESC")
|
||||||
|
add("vars[orderby][query_total_reviews]", "DESC")
|
||||||
|
}
|
||||||
|
"trending" -> {
|
||||||
|
add("vars[orderby]", "meta_value_num")
|
||||||
|
add("vars[meta_key]", "_wp_manga_week_views_value")
|
||||||
|
add("vars[order]", "DESC")
|
||||||
|
}
|
||||||
|
"views" -> {
|
||||||
|
add("vars[orderby]", "meta_value_num")
|
||||||
|
add("vars[meta_key]", "_wp_manga_views")
|
||||||
|
add("vars[order]", "DESC")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
add("vars[orderby]", "date")
|
||||||
|
add("vars[order]", "DESC")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is AdultContentFilter -> {
|
||||||
|
if (filter.state != 0) {
|
||||||
|
add("vars[meta_query][$metaQueryIdx][key]", "manga_adult_content")
|
||||||
|
add(
|
||||||
|
"vars[meta_query][$metaQueryIdx][compare]",
|
||||||
|
if (filter.state == 1) "not exists" else "exists"
|
||||||
|
)
|
||||||
|
|
||||||
|
metaQueryIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is GenreConditionFilter -> {
|
||||||
|
if (filter.state == 1 && genres.isNotEmpty()) {
|
||||||
|
add("vars[tax_query][$taxQueryIdx][operation]", "AND")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is GenreList -> {
|
||||||
|
if (genres.isNotEmpty()) {
|
||||||
|
add("vars[tax_query][$taxQueryIdx][taxonomy]", "wp-manga-genre")
|
||||||
|
add("vars[tax_query][$taxQueryIdx][field]", "slug")
|
||||||
|
|
||||||
|
genres.forEachIndexed { i, slug ->
|
||||||
|
add("vars[tax_query][$taxQueryIdx][terms][$i]", slug)
|
||||||
|
}
|
||||||
|
|
||||||
|
taxQueryIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val searchHeaders = headersBuilder()
|
||||||
|
.add("X-Requested-With", "XMLHttpRequest")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
return POST(
|
||||||
|
"$baseUrl/wp-admin/admin-ajax.php",
|
||||||
|
searchHeaders,
|
||||||
|
formBodyBuilder.build(),
|
||||||
|
CacheControl.FORCE_NETWORK
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
protected open val authorFilterTitle: String = when (lang) {
|
protected open val authorFilterTitle: String = when (lang) {
|
||||||
"pt-BR" -> "Autor"
|
"pt-BR" -> "Autor"
|
||||||
else -> "Author"
|
else -> "Author"
|
||||||
|
@ -258,11 +441,11 @@ abstract class Madara(
|
||||||
|
|
||||||
protected open val orderByFilterOptions: Array<String> = when (lang) {
|
protected open val orderByFilterOptions: Array<String> = when (lang) {
|
||||||
"pt-BR" -> arrayOf(
|
"pt-BR" -> arrayOf(
|
||||||
"<selecione>", "Recentes", "A-Z", "Avaliação",
|
"Relevância", "Recentes", "A-Z", "Avaliação",
|
||||||
"Tendência", "Visualizações", "Novos"
|
"Tendência", "Visualizações", "Novos"
|
||||||
)
|
)
|
||||||
else -> arrayOf(
|
else -> arrayOf(
|
||||||
"<select>", "Latest", "A-Z", "Rating",
|
"Relevance", "Latest", "A-Z", "Rating",
|
||||||
"Trending", "Most Views", "New"
|
"Trending", "Most Views", "New"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -292,7 +475,7 @@ abstract class Madara(
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open val genreFilterHeader: String = when (lang) {
|
protected open val genreFilterHeader: String = when (lang) {
|
||||||
"pt-BR" -> "O filtro de gêneros pode não funcionar em algumas fontes"
|
"pt-BR" -> "O filtro de gêneros pode não funcionar"
|
||||||
else -> "Genres filter may not work for all sources"
|
else -> "Genres filter may not work for all sources"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,9 +484,9 @@ abstract class Madara(
|
||||||
else -> "Genres"
|
else -> "Genres"
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open val genreFilterResetWarning: String = when (lang) {
|
protected open val showOnlyMangaEntriesLabel: String = when (lang) {
|
||||||
"pt-BR" -> "Aperte redefinir para tentar carregar os gêneros"
|
"pt-BR" -> "Mostrar somente mangás"
|
||||||
else -> "Press reset to attempt to fetch genres"
|
else -> "Show only manga entries"
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class AuthorFilter(title: String) : Filter.Text(title)
|
protected class AuthorFilter(title: String) : Filter.Text(title)
|
||||||
|
@ -312,8 +495,8 @@ abstract class Madara(
|
||||||
protected class StatusFilter(title: String, status: List<Tag>) :
|
protected class StatusFilter(title: String, status: List<Tag>) :
|
||||||
Filter.Group<Tag>(title, status)
|
Filter.Group<Tag>(title, status)
|
||||||
|
|
||||||
protected class OrderByFilter(title: String, options: List<Pair<String, String>>) :
|
protected class OrderByFilter(title: String, options: List<Pair<String, String>>, state: Int = 0) :
|
||||||
UriPartFilter(title, options.toTypedArray())
|
UriPartFilter(title, options.toTypedArray(), state)
|
||||||
|
|
||||||
protected class GenreConditionFilter(title: String, options: Array<String>) : UriPartFilter(
|
protected class GenreConditionFilter(title: String, options: Array<String>) : UriPartFilter(
|
||||||
title,
|
title,
|
||||||
|
@ -328,34 +511,46 @@ abstract class Madara(
|
||||||
protected class GenreList(title: String, genres: List<Genre>) : Filter.Group<Genre>(title, genres)
|
protected class GenreList(title: String, genres: List<Genre>) : Filter.Group<Genre>(title, genres)
|
||||||
class Genre(name: String, val id: String = name) : Filter.CheckBox(name)
|
class Genre(name: String, val id: String = name) : Filter.CheckBox(name)
|
||||||
|
|
||||||
private var genresList: List<Genre>? = null
|
protected class ShowOnlyMangaFilter(label: String) : Filter.CheckBox(label, true)
|
||||||
|
|
||||||
protected open fun getGenreList(): List<Genre> {
|
private var genresList: List<Genre> = emptyList()
|
||||||
// Filters are fetched immediately once an extension loads
|
|
||||||
// We're only able to get filters after a loading the manga directory, and resetting
|
override fun getFilterList(): FilterList {
|
||||||
// the filters is the only thing that seems to reinflate the view
|
val filters = mutableListOf(
|
||||||
return genresList ?: listOf(Genre(genreFilterResetWarning, ""))
|
AuthorFilter(authorFilterTitle),
|
||||||
|
ArtistFilter(artistFilterTitle),
|
||||||
|
YearFilter(yearFilterTitle),
|
||||||
|
StatusFilter(statusFilterTitle, getStatusList()),
|
||||||
|
OrderByFilter(
|
||||||
|
orderByFilterTitle,
|
||||||
|
orderByFilterOptions.zip(orderByFilterOptionsValues),
|
||||||
|
if (useLoadMoreSearch) 5 else 0
|
||||||
|
),
|
||||||
|
AdultContentFilter(adultContentFilterTitle, adultContentFilterOptions)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (useLoadMoreSearch) {
|
||||||
|
filters.add(ShowOnlyMangaFilter(showOnlyMangaEntriesLabel))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genresList.isNotEmpty()) {
|
||||||
|
filters += listOf(
|
||||||
|
Filter.Separator(),
|
||||||
|
Filter.Header(genreFilterHeader),
|
||||||
|
GenreConditionFilter(genreConditionFilterTitle, genreConditionFilterOptions),
|
||||||
|
GenreList(genreFilterTitle, genresList)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return FilterList(filters)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
|
||||||
AuthorFilter(authorFilterTitle),
|
|
||||||
ArtistFilter(artistFilterTitle),
|
|
||||||
YearFilter(yearFilterTitle),
|
|
||||||
StatusFilter(statusFilterTitle, getStatusList()),
|
|
||||||
OrderByFilter(orderByFilterTitle, orderByFilterOptions.zip(orderByFilterOptionsValues)),
|
|
||||||
AdultContentFilter(adultContentFilterTitle, adultContentFilterOptions),
|
|
||||||
Filter.Separator(),
|
|
||||||
Filter.Header(genreFilterHeader),
|
|
||||||
GenreConditionFilter(genreConditionFilterTitle, genreConditionFilterOptions),
|
|
||||||
GenreList(genreFilterTitle, getGenreList())
|
|
||||||
)
|
|
||||||
|
|
||||||
protected fun getStatusList() = statusFilterOptionsValues
|
protected fun getStatusList() = statusFilterOptionsValues
|
||||||
.zip(statusFilterOptions)
|
.zip(statusFilterOptions)
|
||||||
.map { Tag(it.first, it.second) }
|
.map { Tag(it.first, it.second) }
|
||||||
|
|
||||||
open class UriPartFilter(displayName: String, private val vals: Array<Pair<String, String>>) :
|
open class UriPartFilter(displayName: String, private val vals: Array<Pair<String, String>>, state: Int = 0) :
|
||||||
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
|
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray(), state) {
|
||||||
fun toUriPart() = vals[state].second
|
fun toUriPart() = vals[state].second
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,7 +784,7 @@ abstract class Madara(
|
||||||
// Added "title" alternative
|
// Added "title" alternative
|
||||||
chapter.date_upload = select("img:not(.thumb)").firstOrNull()?.attr("alt")?.let { parseRelativeDate(it) }
|
chapter.date_upload = select("img:not(.thumb)").firstOrNull()?.attr("alt")?.let { parseRelativeDate(it) }
|
||||||
?: select("span a").firstOrNull()?.attr("title")?.let { parseRelativeDate(it) }
|
?: select("span a").firstOrNull()?.attr("title")?.let { parseRelativeDate(it) }
|
||||||
?: parseChapterDate(select("span.chapter-release-date").firstOrNull()?.text())
|
?: parseChapterDate(select("span.chapter-release-date").firstOrNull()?.text())
|
||||||
}
|
}
|
||||||
|
|
||||||
return chapter
|
return chapter
|
||||||
|
@ -755,8 +950,25 @@ abstract class Madara(
|
||||||
runCatching { client.newCall(request).execute().close() }
|
runCatching { client.newCall(request).execute().close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (fetchGenresOnInit && genresList.isEmpty()) {
|
||||||
|
Single
|
||||||
|
.fromCallable {
|
||||||
|
val genres = runCatching {
|
||||||
|
client.newCall(GET("$baseUrl/?s=&post_type=wp-manga")).execute()
|
||||||
|
.use { parseGenres(it.asJsoup()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
genresList = genres.getOrNull().orEmpty()
|
||||||
|
}
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(Schedulers.io())
|
||||||
|
.subscribe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val URL_SEARCH_PREFIX = "SLUG:"
|
const val URL_SEARCH_PREFIX = "slug:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ class MadaraGenerator : ThemeSourceGenerator {
|
||||||
|
|
||||||
override val themeClass = "Madara"
|
override val themeClass = "Madara"
|
||||||
|
|
||||||
override val baseVersionCode: Int = 17
|
override val baseVersionCode: Int = 18
|
||||||
|
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
MultiLang("Leviatan Scans", "https://leviatanscans.com", listOf("en", "es"), className = "LeviatanScansFactory", overrideVersionCode = 9),
|
MultiLang("Leviatan Scans", "https://leviatanscans.com", listOf("en", "es"), className = "LeviatanScansFactory", overrideVersionCode = 9),
|
||||||
|
|
Loading…
Reference in New Issue