Add genre filter for catalogue (#428)
* Add genre filter for catalogue * Implement genre filter for batoto * hardcode filters for sources * swtich filter id to string * reset filters when switching sources * Add filter support to mangafox * Catalogue changes * Indefinite snackbar on error, use plain subscriptions in catalogue presenter
This commit is contained in:
@@ -47,5 +47,4 @@ interface Source {
|
||||
* @param page the page.
|
||||
*/
|
||||
fun fetchImage(page: Page): Observable<Page>
|
||||
|
||||
}
|
||||
@@ -58,6 +58,11 @@ abstract class OnlineSource(context: Context) : Source {
|
||||
*/
|
||||
val headers by lazy { headersBuilder().build() }
|
||||
|
||||
/**
|
||||
* Genre filters.
|
||||
*/
|
||||
val filters by lazy { getFilterList() }
|
||||
|
||||
/**
|
||||
* Default network client for doing requests.
|
||||
*/
|
||||
@@ -126,11 +131,11 @@ abstract class OnlineSource(context: Context) : Source {
|
||||
* the current page and the next page url.
|
||||
* @param query the search query.
|
||||
*/
|
||||
open fun fetchSearchManga(page: MangasPage, query: String): Observable<MangasPage> = client
|
||||
.newCall(searchMangaRequest(page, query))
|
||||
open fun fetchSearchManga(page: MangasPage, query: String, filters: List<Filter>): Observable<MangasPage> = client
|
||||
.newCall(searchMangaRequest(page, query, filters))
|
||||
.asObservable()
|
||||
.map { response ->
|
||||
searchMangaParse(response, page, query)
|
||||
searchMangaParse(response, page, query, filters)
|
||||
page
|
||||
}
|
||||
|
||||
@@ -141,9 +146,9 @@ abstract class OnlineSource(context: Context) : Source {
|
||||
* @param page the page object.
|
||||
* @param query the search query.
|
||||
*/
|
||||
open protected fun searchMangaRequest(page: MangasPage, query: String): Request {
|
||||
open protected fun searchMangaRequest(page: MangasPage, query: String, filters: List<Filter>): Request {
|
||||
if (page.page == 1) {
|
||||
page.url = searchMangaInitialUrl(query)
|
||||
page.url = searchMangaInitialUrl(query, filters)
|
||||
}
|
||||
return GET(page.url, headers)
|
||||
}
|
||||
@@ -153,7 +158,7 @@ abstract class OnlineSource(context: Context) : Source {
|
||||
*
|
||||
* @param query the search query.
|
||||
*/
|
||||
abstract protected fun searchMangaInitialUrl(query: String): String
|
||||
abstract protected fun searchMangaInitialUrl(query: String, filters: List<Filter>): String
|
||||
|
||||
/**
|
||||
* Parse the response from the site. It should add a list of manga and the absolute url to the
|
||||
@@ -163,7 +168,7 @@ abstract class OnlineSource(context: Context) : Source {
|
||||
* @param page the page object to be filled.
|
||||
* @param query the search query.
|
||||
*/
|
||||
abstract protected fun searchMangaParse(response: Response, page: MangasPage, query: String)
|
||||
abstract protected fun searchMangaParse(response: Response, page: MangasPage, query: String, filters: List<Filter>)
|
||||
|
||||
/**
|
||||
* Returns an observable with the updated details for a manga. Normally it's not needed to
|
||||
@@ -428,4 +433,7 @@ abstract class OnlineSource(context: Context) : Source {
|
||||
|
||||
}
|
||||
|
||||
data class Filter(val id: String, val name: String)
|
||||
|
||||
open fun getFilterList(): List<Filter> = emptyList()
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ abstract class ParsedOnlineSource(context: Context) : OnlineSource(context) {
|
||||
* @param page the page object to be filled.
|
||||
* @param query the search query.
|
||||
*/
|
||||
override fun searchMangaParse(response: Response, page: MangasPage, query: String) {
|
||||
override fun searchMangaParse(response: Response, page: MangasPage, query: String, filters: List<Filter>) {
|
||||
val document = response.asJsoup()
|
||||
for (element in document.select(searchMangaSelector())) {
|
||||
Manga.create(id).apply {
|
||||
@@ -179,5 +179,4 @@ abstract class ParsedOnlineSource(context: Context) : OnlineSource(context) {
|
||||
* @param document the parsed document.
|
||||
*/
|
||||
abstract protected fun imageUrlParse(document: Document): String
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.network.GET
|
||||
import eu.kanade.tachiyomi.data.network.POST
|
||||
import eu.kanade.tachiyomi.data.source.Source
|
||||
import eu.kanade.tachiyomi.data.source.getLanguages
|
||||
import eu.kanade.tachiyomi.data.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.data.source.model.Page
|
||||
@@ -14,6 +15,7 @@ import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Element
|
||||
import rx.Observable
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
@@ -68,9 +70,9 @@ class YamlOnlineSource(context: Context, mappings: Map<*, *>) : OnlineSource(con
|
||||
}
|
||||
}
|
||||
|
||||
override fun searchMangaRequest(page: MangasPage, query: String): Request {
|
||||
override fun searchMangaRequest(page: MangasPage, query: String, filters: List<Filter>): Request {
|
||||
if (page.page == 1) {
|
||||
page.url = searchMangaInitialUrl(query)
|
||||
page.url = searchMangaInitialUrl(query, filters)
|
||||
}
|
||||
return when (map.search.method?.toLowerCase()) {
|
||||
"post" -> POST(page.url, headers, map.search.createForm())
|
||||
@@ -78,9 +80,9 @@ class YamlOnlineSource(context: Context, mappings: Map<*, *>) : OnlineSource(con
|
||||
}
|
||||
}
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) = map.search.url.replace("\$query", query)
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) = map.search.url.replace("\$query", query)
|
||||
|
||||
override fun searchMangaParse(response: Response, page: MangasPage, query: String) {
|
||||
override fun searchMangaParse(response: Response, page: MangasPage, query: String, filters: List<Filter>) {
|
||||
val document = response.asJsoup()
|
||||
for (element in document.select(map.search.manga_css)) {
|
||||
Manga.create(id).apply {
|
||||
@@ -184,5 +186,4 @@ class YamlOnlineSource(context: Context, mappings: Map<*, *>) : OnlineSource(con
|
||||
throw Exception("image_regex and image_css are null")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -84,9 +84,21 @@ class Batoto(context: Context, override val id: Int) : ParsedOnlineSource(contex
|
||||
|
||||
override fun popularMangaNextPageSelector() = "#show_more_row"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) = "$baseUrl/search_ajax?name=${Uri.encode(query)}&p=1"
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) = "$baseUrl/search_ajax?name=${Uri.encode(query)}&order_cond=views&order=desc&p=1&genre_cond=and&genres=${getFilterParams(filters)}"
|
||||
|
||||
override fun searchMangaParse(response: Response, page: MangasPage, query: String) {
|
||||
private fun getFilterParams(filters: List<Filter>): String = filters
|
||||
.map {
|
||||
";i" + it.id
|
||||
}.joinToString()
|
||||
|
||||
override fun searchMangaRequest(page: MangasPage, query: String, filters: List<Filter>): Request {
|
||||
if (page.page == 1) {
|
||||
page.url = searchMangaInitialUrl(query, filters)
|
||||
}
|
||||
return GET(page.url, headers)
|
||||
}
|
||||
|
||||
override fun searchMangaParse(response: Response, page: MangasPage, query: String, filters: List<Filter>) {
|
||||
val document = response.asJsoup()
|
||||
for (element in document.select(searchMangaSelector())) {
|
||||
Manga.create(id).apply {
|
||||
@@ -96,7 +108,7 @@ class Batoto(context: Context, override val id: Int) : ParsedOnlineSource(contex
|
||||
}
|
||||
|
||||
page.nextPageUrl = document.select(searchMangaNextPageSelector()).first()?.let {
|
||||
"$baseUrl/search_ajax?name=${Uri.encode(query)}&p=${page.page + 1}"
|
||||
"$baseUrl/search_ajax?name=${Uri.encode(query)}&p=${page.page + 1}&order_cond=views&order=desc&genre_cond=and&genres=" + getFilterParams(filters)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +223,7 @@ class Batoto(context: Context, override val id: Int) : ParsedOnlineSource(contex
|
||||
val start = pageUrl.indexOf("#") + 1
|
||||
val end = pageUrl.indexOf("_", start)
|
||||
val id = pageUrl.substring(start, end)
|
||||
return GET("$baseUrl/areader?id=$id&p=${pageUrl.substring(end+1)}", pageHeaders)
|
||||
return GET("$baseUrl/areader?id=$id&p=${pageUrl.substring(end + 1)}", pageHeaders)
|
||||
}
|
||||
|
||||
override fun imageUrlParse(document: Document): String {
|
||||
@@ -219,10 +231,10 @@ class Batoto(context: Context, override val id: Int) : ParsedOnlineSource(contex
|
||||
}
|
||||
|
||||
override fun login(username: String, password: String) =
|
||||
client.newCall(GET("$baseUrl/forums/index.php?app=core&module=global§ion=login", headers))
|
||||
.asObservable()
|
||||
.flatMap { doLogin(it, username, password) }
|
||||
.map { isAuthenticationSuccessful(it) }
|
||||
client.newCall(GET("$baseUrl/forums/index.php?app=core&module=global§ion=login", headers))
|
||||
.asObservable()
|
||||
.flatMap { doLogin(it, username, password) }
|
||||
.map { isAuthenticationSuccessful(it) }
|
||||
|
||||
private fun doLogin(response: Response, username: String, password: String): Observable<Response> {
|
||||
val doc = response.asJsoup()
|
||||
@@ -242,7 +254,7 @@ class Batoto(context: Context, override val id: Int) : ParsedOnlineSource(contex
|
||||
}
|
||||
|
||||
override fun isAuthenticationSuccessful(response: Response) =
|
||||
response.priorResponse() != null && response.priorResponse().code() == 302
|
||||
response.priorResponse() != null && response.priorResponse().code() == 302
|
||||
|
||||
override fun isLogged(): Boolean {
|
||||
return network.cookies.get(URI(baseUrl)).any { it.name() == "pass_hash" }
|
||||
@@ -264,4 +276,48 @@ class Batoto(context: Context, override val id: Int) : ParsedOnlineSource(contex
|
||||
}
|
||||
}
|
||||
|
||||
// [...document.querySelectorAll("#advanced_options div.genre_buttons")].map((el,i) => {
|
||||
// const onClick=el.getAttribute('onclick');const id=onClick.substr(14,onClick.length-16);return `Filter("${id}", "${el.textContent.trim()}")`
|
||||
// }).join(',\n')
|
||||
// on https://bato.to/search
|
||||
override fun getFilterList(): List<Filter> = listOf(
|
||||
Filter("40", "4-Koma"),
|
||||
Filter("1", "Action"),
|
||||
Filter("2", "Adventure"),
|
||||
Filter("39", "Award Winning"),
|
||||
Filter("3", "Comedy"),
|
||||
Filter("41", "Cooking"),
|
||||
Filter("9", "Doujinshi"),
|
||||
Filter("10", "Drama"),
|
||||
Filter("12", "Ecchi"),
|
||||
Filter("13", "Fantasy"),
|
||||
Filter("15", "Gender Bender"),
|
||||
Filter("17", "Harem"),
|
||||
Filter("20", "Historical"),
|
||||
Filter("22", "Horror"),
|
||||
Filter("34", "Josei"),
|
||||
Filter("27", "Martial Arts"),
|
||||
Filter("30", "Mecha"),
|
||||
Filter("42", "Medical"),
|
||||
Filter("37", "Music"),
|
||||
Filter("4", "Mystery"),
|
||||
Filter("38", "Oneshot"),
|
||||
Filter("5", "Psychological"),
|
||||
Filter("6", "Romance"),
|
||||
Filter("7", "School Life"),
|
||||
Filter("8", "Sci-fi"),
|
||||
Filter("32", "Seinen"),
|
||||
Filter("35", "Shoujo"),
|
||||
Filter("16", "Shoujo Ai"),
|
||||
Filter("33", "Shounen"),
|
||||
Filter("19", "Shounen Ai"),
|
||||
Filter("21", "Slice of Life"),
|
||||
Filter("23", "Smut"),
|
||||
Filter("25", "Sports"),
|
||||
Filter("26", "Supernatural"),
|
||||
Filter("28", "Tragedy"),
|
||||
Filter("36", "Webtoon"),
|
||||
Filter("29", "Yaoi"),
|
||||
Filter("31", "Yuri")
|
||||
)
|
||||
}
|
||||
@@ -42,22 +42,34 @@ class Kissmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
|
||||
|
||||
override fun popularMangaNextPageSelector() = "li > a:contains(› Next)"
|
||||
|
||||
override fun searchMangaRequest(page: MangasPage, query: String): Request {
|
||||
override fun searchMangaRequest(page: MangasPage, query: String, filters: List<Filter>): Request {
|
||||
if (page.page == 1) {
|
||||
page.url = searchMangaInitialUrl(query)
|
||||
page.url = searchMangaInitialUrl(query, filters)
|
||||
}
|
||||
|
||||
val form = FormBody.Builder().apply {
|
||||
add("authorArtist", "")
|
||||
add("mangaName", query)
|
||||
add("status", "")
|
||||
add("genres", "")
|
||||
}.build()
|
||||
}
|
||||
|
||||
return POST(page.url, headers, form)
|
||||
val filterIndexes = filters.map { it.id.toInt() }
|
||||
val maxFilterIndex = filterIndexes.max()
|
||||
|
||||
if (maxFilterIndex !== null) {
|
||||
for (i in 0..maxFilterIndex) {
|
||||
form.add("genres", if (filterIndexes.contains(i)) {
|
||||
"1"
|
||||
} else {
|
||||
"0"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return POST(page.url, headers, form.build())
|
||||
}
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) = "$baseUrl/AdvanceSearch"
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) = "$baseUrl/AdvanceSearch"
|
||||
|
||||
override fun searchMangaSelector() = popularMangaSelector()
|
||||
|
||||
@@ -73,7 +85,7 @@ class Kissmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
|
||||
manga.author = infoElement.select("p:has(span:contains(Author:)) > a").first()?.text()
|
||||
manga.genre = infoElement.select("p:has(span:contains(Genres:)) > *:gt(0)").text()
|
||||
manga.description = infoElement.select("p:has(span:contains(Summary:)) ~ p").text()
|
||||
manga.status = infoElement.select("p:has(span:contains(Status:))").first()?.text().orEmpty().let { parseStatus(it)}
|
||||
manga.status = infoElement.select("p:has(span:contains(Status:))").first()?.text().orEmpty().let { parseStatus(it) }
|
||||
manga.thumbnail_url = document.select(".rightBox:eq(0) img").first()?.attr("src")
|
||||
}
|
||||
|
||||
@@ -109,10 +121,59 @@ class Kissmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
|
||||
}
|
||||
|
||||
// Not used
|
||||
override fun pageListParse(document: Document, pages: MutableList<Page>) {}
|
||||
override fun pageListParse(document: Document, pages: MutableList<Page>) {
|
||||
}
|
||||
|
||||
override fun imageUrlRequest(page: Page) = GET(page.url)
|
||||
|
||||
override fun imageUrlParse(document: Document) = ""
|
||||
|
||||
// $("select[name=\"genres\"]").map((i,el) => `Filter("${i}", "${$(el).next().text().trim()}")`).get().join(',\n')
|
||||
// on http://kissmanga.com/AdvanceSearch
|
||||
override fun getFilterList(): List<Filter> = listOf(
|
||||
Filter("0", "Action"),
|
||||
Filter("1", "Adult"),
|
||||
Filter("2", "Adventure"),
|
||||
Filter("3", "Comedy"),
|
||||
Filter("4", "Comic"),
|
||||
Filter("5", "Cooking"),
|
||||
Filter("6", "Doujinshi"),
|
||||
Filter("7", "Drama"),
|
||||
Filter("8", "Ecchi"),
|
||||
Filter("9", "Fantasy"),
|
||||
Filter("10", "Gender Bender"),
|
||||
Filter("11", "Harem"),
|
||||
Filter("12", "Historical"),
|
||||
Filter("13", "Horror"),
|
||||
Filter("14", "Josei"),
|
||||
Filter("15", "Lolicon"),
|
||||
Filter("16", "Manga"),
|
||||
Filter("17", "Manhua"),
|
||||
Filter("18", "Manhwa"),
|
||||
Filter("19", "Martial Arts"),
|
||||
Filter("20", "Mature"),
|
||||
Filter("21", "Mecha"),
|
||||
Filter("22", "Medical"),
|
||||
Filter("23", "Music"),
|
||||
Filter("24", "Mystery"),
|
||||
Filter("25", "One shot"),
|
||||
Filter("26", "Psychological"),
|
||||
Filter("27", "Romance"),
|
||||
Filter("28", "School Life"),
|
||||
Filter("29", "Sci-fi"),
|
||||
Filter("30", "Seinen"),
|
||||
Filter("31", "Shotacon"),
|
||||
Filter("32", "Shoujo"),
|
||||
Filter("33", "Shoujo Ai"),
|
||||
Filter("34", "Shounen"),
|
||||
Filter("35", "Shounen Ai"),
|
||||
Filter("36", "Slice of Life"),
|
||||
Filter("37", "Smut"),
|
||||
Filter("38", "Sports"),
|
||||
Filter("39", "Supernatural"),
|
||||
Filter("40", "Tragedy"),
|
||||
Filter("41", "Webtoon"),
|
||||
Filter("42", "Yaoi"),
|
||||
Filter("43", "Yuri")
|
||||
)
|
||||
}
|
||||
@@ -36,8 +36,8 @@ class Mangafox(context: Context, override val id: Int) : ParsedOnlineSource(cont
|
||||
|
||||
override fun popularMangaNextPageSelector() = "a:has(span.next)"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) =
|
||||
"$baseUrl/search.php?name_method=cw&advopts=1&order=za&sort=views&name=$query&page=1"
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) =
|
||||
"$baseUrl/search.php?name_method=cw&advopts=1&order=za&sort=views&name=$query&page=1&${filters.map { it.id + "=1" }.joinToString("&")}"
|
||||
|
||||
override fun searchMangaSelector() = "table#listing > tbody > tr:gt(0)"
|
||||
|
||||
@@ -118,4 +118,43 @@ class Mangafox(context: Context, override val id: Int) : ParsedOnlineSource(cont
|
||||
|
||||
override fun imageUrlParse(document: Document) = document.getElementById("image").attr("src")
|
||||
|
||||
// $('select.genres').map((i,el)=>`Filter("${$(el).attr('name')}", "${$(el).next().text().trim()}")`).get().join(',\n')
|
||||
// on http://kissmanga.com/AdvanceSearch
|
||||
override fun getFilterList(): List<Filter> = listOf(
|
||||
Filter("genres[Action]", "Action"),
|
||||
Filter("genres[Adult]", "Adult"),
|
||||
Filter("genres[Adventure]", "Adventure"),
|
||||
Filter("genres[Comedy]", "Comedy"),
|
||||
Filter("genres[Doujinshi]", "Doujinshi"),
|
||||
Filter("genres[Drama]", "Drama"),
|
||||
Filter("genres[Ecchi]", "Ecchi"),
|
||||
Filter("genres[Fantasy]", "Fantasy"),
|
||||
Filter("genres[Gender Bender]", "Gender Bender"),
|
||||
Filter("genres[Harem]", "Harem"),
|
||||
Filter("genres[Historical]", "Historical"),
|
||||
Filter("genres[Horror]", "Horror"),
|
||||
Filter("genres[Josei]", "Josei"),
|
||||
Filter("genres[Martial Arts]", "Martial Arts"),
|
||||
Filter("genres[Mature]", "Mature"),
|
||||
Filter("genres[Mecha]", "Mecha"),
|
||||
Filter("genres[Mystery]", "Mystery"),
|
||||
Filter("genres[One Shot]", "One Shot"),
|
||||
Filter("genres[Psychological]", "Psychological"),
|
||||
Filter("genres[Romance]", "Romance"),
|
||||
Filter("genres[School Life]", "School Life"),
|
||||
Filter("genres[Sci-fi]", "Sci-fi"),
|
||||
Filter("genres[Seinen]", "Seinen"),
|
||||
Filter("genres[Shoujo]", "Shoujo"),
|
||||
Filter("genres[Shoujo Ai]", "Shoujo Ai"),
|
||||
Filter("genres[Shounen]", "Shounen"),
|
||||
Filter("genres[Shounen Ai]", "Shounen Ai"),
|
||||
Filter("genres[Slice of Life]", "Slice of Life"),
|
||||
Filter("genres[Smut]", "Smut"),
|
||||
Filter("genres[Sports]", "Sports"),
|
||||
Filter("genres[Supernatural]", "Supernatural"),
|
||||
Filter("genres[Tragedy]", "Tragedy"),
|
||||
Filter("genres[Webtoons]", "Webtoons"),
|
||||
Filter("genres[Yaoi]", "Yaoi"),
|
||||
Filter("genres[Yuri]", "Yuri")
|
||||
)
|
||||
}
|
||||
@@ -34,7 +34,7 @@ class Mangahere(context: Context, override val id: Int) : ParsedOnlineSource(con
|
||||
|
||||
override fun popularMangaNextPageSelector() = "div.next-page > a.next"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) =
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) =
|
||||
"$baseUrl/search.php?name=$query&page=1&sort=views&order=za"
|
||||
|
||||
override fun searchMangaSelector() = "div.result_search > dl:has(dt)"
|
||||
|
||||
@@ -47,7 +47,7 @@ class Mangasee(context: Context, override val id: Int) : ParsedOnlineSource(cont
|
||||
|
||||
override fun popularMangaNextPageSelector() = "ul.pagination > li > a:contains(Next)"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) =
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) =
|
||||
"$baseUrl/advanced-search/result.php?sortBy=alphabet&direction=ASC&textOnly=no&resPerPage=20&page=1&seriesName=$query"
|
||||
|
||||
override fun searchMangaSelector() = "div.row > div > div > div > h1"
|
||||
|
||||
@@ -6,8 +6,10 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.network.POST
|
||||
import eu.kanade.tachiyomi.data.source.EN
|
||||
import eu.kanade.tachiyomi.data.source.Language
|
||||
import eu.kanade.tachiyomi.data.source.Source
|
||||
import eu.kanade.tachiyomi.data.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.data.source.model.Page
|
||||
import eu.kanade.tachiyomi.data.source.online.OnlineSource
|
||||
import eu.kanade.tachiyomi.data.source.online.ParsedOnlineSource
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
@@ -38,16 +40,16 @@ class Readmangatoday(context: Context, override val id: Int) : ParsedOnlineSourc
|
||||
|
||||
override fun popularMangaNextPageSelector() = "div.hot-manga > ul.pagination > li > a:contains(»)"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) =
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) =
|
||||
"$baseUrl/search"
|
||||
|
||||
|
||||
override fun searchMangaRequest(page: MangasPage, query: String): Request {
|
||||
override fun searchMangaRequest(page: MangasPage, query: String, filters: List<OnlineSource.Filter>): Request {
|
||||
if (page.page == 1) {
|
||||
page.url = searchMangaInitialUrl(query)
|
||||
page.url = searchMangaInitialUrl(query, filters)
|
||||
}
|
||||
|
||||
var builder = okhttp3.FormBody.Builder()
|
||||
val builder = okhttp3.FormBody.Builder()
|
||||
builder.add("query", query)
|
||||
|
||||
return POST(page.url, headers, builder.build())
|
||||
|
||||
@@ -36,7 +36,7 @@ class WieManga(context: Context, override val id: Int) : ParsedOnlineSource(cont
|
||||
|
||||
override fun popularMangaNextPageSelector() = null
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) = "$baseUrl/search/?wd=$query"
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) = "$baseUrl/search/?wd=$query"
|
||||
|
||||
override fun searchMangaSelector() = ".searchresult td > div"
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class Mangachan(context: Context, override val id: Int) : ParsedOnlineSource(con
|
||||
|
||||
override fun popularMangaInitialUrl() = "$baseUrl/mostfavorites"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) = "$baseUrl/?do=search&subaction=search&story=$query"
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) = "$baseUrl/?do=search&subaction=search&story=$query"
|
||||
|
||||
override fun popularMangaSelector() = "div.content_row"
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class Mintmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
|
||||
|
||||
override fun popularMangaInitialUrl() = "$baseUrl/list?sortType=rate"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) = "$baseUrl/search?q=$query"
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) = "$baseUrl/search?q=$query"
|
||||
|
||||
override fun popularMangaSelector() = "div.desc"
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class Readmanga(context: Context, override val id: Int) : ParsedOnlineSource(con
|
||||
|
||||
override fun popularMangaInitialUrl() = "$baseUrl/list?sortType=rate"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String) = "$baseUrl/search?q=$query"
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) = "$baseUrl/search?q=$query"
|
||||
|
||||
override fun popularMangaSelector() = "div.desc"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user