Some improvements for russian catalogs (#540)
* Implemented genre filter for Mangachan * Fixed search for Mangachan * Changed url with latest updates for Mangachan * Updated genres for Readmanga * Removed duplicate code for Readmanga
This commit is contained in:
parent
b28ef61618
commit
a13ebc3975
3 changed files with 125 additions and 29 deletions
|
@ -1,12 +1,13 @@
|
|||
package eu.kanade.tachiyomi.data.source.online.russian
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.source.Language
|
||||
import eu.kanade.tachiyomi.data.source.RU
|
||||
import eu.kanade.tachiyomi.data.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.data.source.model.Page
|
||||
import eu.kanade.tachiyomi.data.source.online.ParsedOnlineSource
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
|
@ -25,13 +26,25 @@ class Mangachan(override val id: Int) : ParsedOnlineSource() {
|
|||
|
||||
override fun popularMangaInitialUrl() = "$baseUrl/mostfavorites"
|
||||
|
||||
override fun latestUpdatesInitialUrl() = "$baseUrl/manga/new"
|
||||
override fun latestUpdatesInitialUrl() = "$baseUrl/newestch"
|
||||
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>) = "$baseUrl/?do=search&subaction=search&story=$query"
|
||||
override fun searchMangaInitialUrl(query: String, filters: List<Filter>): String {
|
||||
if (query.isNotEmpty()) {
|
||||
return "$baseUrl/?do=search&subaction=search&story=$query"
|
||||
} else if (filters.isNotEmpty()) {
|
||||
var genres = ""
|
||||
filters.forEach { genres = genres + it.name + '+' }
|
||||
return "$baseUrl/tags/${genres.dropLast(1)}"
|
||||
} else {
|
||||
return "$baseUrl/?do=search&subaction=search&story=$query"
|
||||
}
|
||||
}
|
||||
|
||||
override fun popularMangaSelector() = "div.content_row"
|
||||
|
||||
override fun latestUpdatesSelector() = "div.content_row"
|
||||
override fun latestUpdatesSelector() = "ul.area_rightNews li"
|
||||
|
||||
override fun searchMangaSelector() = popularMangaSelector()
|
||||
|
||||
override fun popularMangaFromElement(element: Element, manga: Manga) {
|
||||
element.select("h2 > a").first().let {
|
||||
|
@ -41,20 +54,48 @@ class Mangachan(override val id: Int) : ParsedOnlineSource() {
|
|||
}
|
||||
|
||||
override fun latestUpdatesFromElement(element: Element, manga: Manga) {
|
||||
popularMangaFromElement(element, manga)
|
||||
element.select("a:nth-child(1)").first().let {
|
||||
manga.setUrlWithoutDomain(it.attr("href"))
|
||||
manga.title = it.text()
|
||||
}
|
||||
}
|
||||
|
||||
override fun popularMangaNextPageSelector() = "a:contains(Вперед)"
|
||||
|
||||
override fun latestUpdatesNextPageSelector() = "a:contains(Вперед)"
|
||||
|
||||
override fun searchMangaSelector() = popularMangaSelector()
|
||||
|
||||
override fun searchMangaFromElement(element: Element, manga: Manga) {
|
||||
popularMangaFromElement(element, manga)
|
||||
}
|
||||
|
||||
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
|
||||
override fun popularMangaNextPageSelector() = "a:contains(Вперед)"
|
||||
|
||||
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
|
||||
|
||||
override fun searchMangaNextPageSelector() = "a:contains(Далее)"
|
||||
|
||||
private fun searchGenresNextPageSelector() = popularMangaNextPageSelector()
|
||||
|
||||
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 {
|
||||
searchMangaFromElement(element, this)
|
||||
page.mangas.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
searchMangaNextPageSelector().let { selector ->
|
||||
if (page.nextPageUrl.isNullOrEmpty() && filters.isEmpty()) {
|
||||
val onClick = document.select(selector).first()?.attr("onclick")
|
||||
val pageNum = onClick?.substring(23, onClick.indexOf("); return(false)"))
|
||||
page.nextPageUrl = searchMangaInitialUrl(query, emptyList()) + "&search_start=" + pageNum
|
||||
}
|
||||
}
|
||||
|
||||
searchGenresNextPageSelector().let { selector ->
|
||||
if (page.nextPageUrl.isNullOrEmpty() && filters.isNotEmpty()) {
|
||||
val url = document.select(selector).first()?.attr("href")
|
||||
page.nextPageUrl = searchMangaInitialUrl(query, filters) + url
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun mangaDetailsParse(document: Document, manga: Manga) {
|
||||
val infoElement = document.select("table.mangatitle").first()
|
||||
|
@ -95,13 +136,74 @@ class Mangachan(override val id: Int) : ParsedOnlineSource() {
|
|||
val trimmedHtml = html.substring(beginIndex, endIndex).replace("\"", "")
|
||||
val pageUrls = trimmedHtml.split(',')
|
||||
|
||||
for ((i, url) in pageUrls.withIndex()) {
|
||||
pages.add(Page(i, "", url))
|
||||
}
|
||||
pageUrls.mapIndexedTo(pages) { i, url -> Page(i, "", url) }
|
||||
}
|
||||
|
||||
override fun pageListParse(document: Document, pages: MutableList<Page>) { }
|
||||
|
||||
override fun imageUrlParse(document: Document) = ""
|
||||
|
||||
/* [...document.querySelectorAll("li.sidetag > a:nth-child(1)")].map((el,i) =>
|
||||
* { const link=el.getAttribute('href');const id=link.substr(6,link.length);
|
||||
* return `Filter("${id}", "${id}")` }).join(',\n')
|
||||
* on http://mangachan.me/
|
||||
*/
|
||||
override fun getFilterList(): List<Filter> = listOf(
|
||||
Filter("18_плюс", "18_плюс"),
|
||||
Filter("bdsm", "bdsm"),
|
||||
Filter("арт", "арт"),
|
||||
Filter("биография", "биография"),
|
||||
Filter("боевик", "боевик"),
|
||||
Filter("боевые_искусства", "боевые_искусства"),
|
||||
Filter("вампиры", "вампиры"),
|
||||
Filter("веб", "веб"),
|
||||
Filter("гарем", "гарем"),
|
||||
Filter("гендерная_интрига", "гендерная_интрига"),
|
||||
Filter("героическое_фэнтези", "героическое_фэнтези"),
|
||||
Filter("детектив", "детектив"),
|
||||
Filter("дзёсэй", "дзёсэй"),
|
||||
Filter("додзинси", "додзинси"),
|
||||
Filter("драма", "драма"),
|
||||
Filter("игра", "игра"),
|
||||
Filter("инцест", "инцест"),
|
||||
Filter("искусство", "искусство"),
|
||||
Filter("история", "история"),
|
||||
Filter("киберпанк", "киберпанк"),
|
||||
Filter("кодомо", "кодомо"),
|
||||
Filter("комедия", "комедия"),
|
||||
Filter("литРПГ", "литРПГ"),
|
||||
Filter("махо-сёдзё", "махо-сёдзё"),
|
||||
Filter("меха", "меха"),
|
||||
Filter("мистика", "мистика"),
|
||||
Filter("музыка", "музыка"),
|
||||
Filter("научная_фантастика", "научная_фантастика"),
|
||||
Filter("повседневность", "повседневность"),
|
||||
Filter("постапокалиптика", "постапокалиптика"),
|
||||
Filter("приключения", "приключения"),
|
||||
Filter("психология", "психология"),
|
||||
Filter("романтика", "романтика"),
|
||||
Filter("самурайский_боевик", "самурайский_боевик"),
|
||||
Filter("сборник", "сборник"),
|
||||
Filter("сверхъестественное", "сверхъестественное"),
|
||||
Filter("сказка", "сказка"),
|
||||
Filter("спорт", "спорт"),
|
||||
Filter("супергерои", "супергерои"),
|
||||
Filter("сэйнэн", "сэйнэн"),
|
||||
Filter("сёдзё", "сёдзё"),
|
||||
Filter("сёдзё-ай", "сёдзё-ай"),
|
||||
Filter("сёнэн", "сёнэн"),
|
||||
Filter("сёнэн-ай", "сёнэн-ай"),
|
||||
Filter("тентакли", "тентакли"),
|
||||
Filter("трагедия", "трагедия"),
|
||||
Filter("триллер", "триллер"),
|
||||
Filter("ужасы", "ужасы"),
|
||||
Filter("фантастика", "фантастика"),
|
||||
Filter("фурри", "фурри"),
|
||||
Filter("фэнтези", "фэнтези"),
|
||||
Filter("школа", "школа"),
|
||||
Filter("эротика", "эротика"),
|
||||
Filter("юри", "юри"),
|
||||
Filter("яой", "яой"),
|
||||
Filter("ёнкома", "ёнкома")
|
||||
)
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.data.source.online.russian
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.source.Language
|
||||
|
@ -115,9 +114,9 @@ class Mintmanga(override val id: Int) : ParsedOnlineSource() {
|
|||
override fun imageUrlParse(document: Document) = ""
|
||||
|
||||
/* [...document.querySelectorAll("tr.advanced_option:nth-child(1) > td:nth-child(3) span.js-link")].map((el,i) => {
|
||||
* const onClick=el.getAttribute('onclick');const id=onClick.substr(31,onClick.length-33);
|
||||
* return `Filter("${id}", "${el.textContent.trim()}")` }).join(',\n')
|
||||
* on http://mintmanga.com/search
|
||||
* const onClick=el.getAttribute('onclick');const id=onClick.substr(31,onClick.length-33);
|
||||
* return `Filter("${id}", "${el.textContent.trim()}")` }).join(',\n')
|
||||
* on http://mintmanga.com/search
|
||||
*/
|
||||
override fun getFilterList(): List<Filter> = listOf(
|
||||
Filter("el_2220", "арт"),
|
||||
|
@ -163,5 +162,4 @@ class Mintmanga(override val id: Int) : ParsedOnlineSource() {
|
|||
Filter("el_1315", "юри"),
|
||||
Filter("el_1336", "яой")
|
||||
)
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.data.source.online.russian
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.source.Language
|
||||
|
@ -53,10 +52,7 @@ class Readmanga(override val id: Int) : ParsedOnlineSource() {
|
|||
override fun searchMangaSelector() = popularMangaSelector()
|
||||
|
||||
override fun searchMangaFromElement(element: Element, manga: Manga) {
|
||||
element.select("h3 > a").first().let {
|
||||
manga.setUrlWithoutDomain(it.attr("href"))
|
||||
manga.title = it.attr("title")
|
||||
}
|
||||
popularMangaFromElement(element, manga)
|
||||
}
|
||||
|
||||
// max 200 results
|
||||
|
@ -118,9 +114,9 @@ class Readmanga(override val id: Int) : ParsedOnlineSource() {
|
|||
override fun imageUrlParse(document: Document) = ""
|
||||
|
||||
/* [...document.querySelectorAll("tr.advanced_option:nth-child(1) > td:nth-child(3) span.js-link")].map((el,i) => {
|
||||
* const onClick=el.getAttribute('onclick');const id=onClick.substr(31,onClick.length-33);
|
||||
* return `Filter("${id}", "${el.textContent.trim()}")` }).join(',\n')
|
||||
* on http://readmanga.me/search
|
||||
* const onClick=el.getAttribute('onclick');const id=onClick.substr(31,onClick.length-33);
|
||||
* return `Filter("${id}", "${el.textContent.trim()}")` }).join(',\n')
|
||||
* on http://readmanga.me/search
|
||||
*/
|
||||
override fun getFilterList(): List<Filter> = listOf(
|
||||
Filter("el_5685", "арт"),
|
||||
|
@ -136,6 +132,7 @@ class Readmanga(override val id: Int) : ParsedOnlineSource() {
|
|||
Filter("el_2118", "драма"),
|
||||
Filter("el_2154", "игра"),
|
||||
Filter("el_2119", "история"),
|
||||
Filter("el_8032", "киберпанк"),
|
||||
Filter("el_2137", "кодомо"),
|
||||
Filter("el_2136", "комедия"),
|
||||
Filter("el_2147", "махо-сёдзё"),
|
||||
|
@ -164,5 +161,4 @@ class Readmanga(override val id: Int) : ParsedOnlineSource() {
|
|||
Filter("el_2149", "этти"),
|
||||
Filter("el_2123", "юри")
|
||||
)
|
||||
|
||||
}
|
Reference in a new issue