From b39be24f683cb22ec6cc28fe97916472bf838d62 Mon Sep 17 00:00:00 2001 From: Rama Bondan Prakoso Date: Tue, 21 Jul 2020 16:25:39 +0700 Subject: [PATCH] MangaJar: Fixes and add filters (#3861) * MangaJar: fix thumbnail Signed-off-by: Rama Bondan Prakoso * MangaJar: Fix manga description and chapter list Signed-off-by: Rama Bondan Prakoso * MangaJar: Add genre filter Signed-off-by: Rama Bondan Prakoso * MangaJar: Sort filters Signed-off-by: Rama Bondan Prakoso * MangaJar: Fix title Signed-off-by: Rama Bondan Prakoso --- src/en/mangajar/build.gradle | 2 +- .../extension/en/mangajar/MangaJar.kt | 114 ++++++++++++++++-- 2 files changed, 108 insertions(+), 8 deletions(-) diff --git a/src/en/mangajar/build.gradle b/src/en/mangajar/build.gradle index 50ea03ec3..34dc06489 100644 --- a/src/en/mangajar/build.gradle +++ b/src/en/mangajar/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'MangaJar' pkgNameSuffix = 'en.mangajar' extClass = '.MangaJar' - extVersionCode = 1 + extVersionCode = 2 libVersion = '1.2' } diff --git a/src/en/mangajar/src/eu/kanade/tachiyomi/extension/en/mangajar/MangaJar.kt b/src/en/mangajar/src/eu/kanade/tachiyomi/extension/en/mangajar/MangaJar.kt index c07aa0c24..797621e77 100644 --- a/src/en/mangajar/src/eu/kanade/tachiyomi/extension/en/mangajar/MangaJar.kt +++ b/src/en/mangajar/src/eu/kanade/tachiyomi/extension/en/mangajar/MangaJar.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.extension.en.mangajar import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter @@ -9,6 +10,7 @@ import eu.kanade.tachiyomi.source.online.ParsedHttpSource import java.text.SimpleDateFormat import java.util.Calendar import java.util.Locale +import okhttp3.HttpUrl import okhttp3.OkHttpClient import okhttp3.Request import org.jsoup.nodes.Document @@ -26,7 +28,7 @@ class MangaJar : ParsedHttpSource() { override val client: OkHttpClient = network.cloudflareClient - override fun popularMangaSelector() = "article:has(div.post-description)" + override fun popularMangaSelector() = "article[class*=flex-item]" override fun popularMangaRequest(page: Int): Request { return GET("$baseUrl/manga?sortBy=popular&page=$page") @@ -40,8 +42,9 @@ class MangaJar : ParsedHttpSource() { override fun popularMangaFromElement(element: Element) = SManga.create().apply { setUrlWithoutDomain(element.select("a").attr("href")) - title = element.select("p.card-title.js-card-title").text() - thumbnail_url = element.select("img").attr("src") + title = element.select("img").attr("title") + thumbnail_url = element.select("img").let { if (it.hasAttr("data-src")) + it.attr("data-src") else it.attr("src") } } override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element) @@ -51,7 +54,27 @@ class MangaJar : ParsedHttpSource() { override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - return GET("$baseUrl/search?q=$query&page=$page") + val filters = if (filters.isEmpty()) getFilterList() else filters + val genreFilter = filters.findInstance() + val genre = genreFilter?.let { f -> f.values[f.state] } + + val url = HttpUrl.parse(if (genre!!.isEmpty()) "$baseUrl/search" else "$baseUrl/genre/$genre")!!.newBuilder() + + url.addQueryParameter("q", query) + url.addQueryParameter("page", page.toString()) + + (filters.forEach { filter -> + when (filter) { + is OrderBy -> { + url.addQueryParameter("sortBy", filter.toUriPart()) + } + is SortBy -> { + url.addQueryParameter("sortAscending", filter.toUriPart()) + } + } + }) + + return GET(url.toString(), headers) } override fun searchMangaSelector() = popularMangaSelector() @@ -61,7 +84,7 @@ class MangaJar : ParsedHttpSource() { override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun mangaDetailsParse(document: Document) = SManga.create().apply { - description = document.select("div.manga-description.entry > div").text() + description = document.select("div.manga-description.entry").text() thumbnail_url = document.select("div.row > div > img").attr("src") genre = document.select("div.post-info > span > a[href*=genre]").joinToString { it.text() } status = parseStatus(document.select("span:has(b)")[1].text()) @@ -75,7 +98,7 @@ class MangaJar : ParsedHttpSource() { override fun chapterListRequest(manga: SManga) = GET(baseUrl + manga.url + "/chaptersList") - override fun chapterListSelector() = "li.list-group-item.chapter-item.d-none" + override fun chapterListSelector() = "li.list-group-item.chapter-item" override fun chapterFromElement(element: Element) = SChapter.create().apply { setUrlWithoutDomain(element.select("a").attr("href")) @@ -122,5 +145,82 @@ class MangaJar : ParsedHttpSource() { override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not Used") - override fun getFilterList() = FilterList() + override fun getFilterList() = FilterList( + OrderBy(), + SortBy(), + GenreList() + ) + + private class SortBy : UriPartFilter("Sort By", arrayOf( + Pair("Descending", "0"), + Pair("Ascending", "1") + )) + + private class OrderBy : UriPartFilter("Order By", arrayOf( + Pair("Popularity", "popular"), + Pair("Year", "year"), + Pair("Alphabet", "name"), + Pair("Date added", "published_at"), + Pair("Date updated", "last_chapter_at") + )) + + private class GenreList : Filter.Select("Select Genre", + arrayOf( + "", + "Fantasy", + "Adventure", + "Martial Arts", + "Action", + "Demons", + "Shounen", + "Drama", + "Isekai", + "School Life", + "Harem", + "Horror", + "Supernatural", + "Mystery", + "Sci-Fi", + "Webtoons", + "Romance", + "Magic", + "Slice of Life", + "Seinen", + "Historical", + "Ecchi", + "Comedy", + "Sports", + "Tragedy", + "Shounen Ai", + "Yaoi", + "Shoujo", + "Super Power", + "Food", + "Psychological", + "Gender Bender", + "Smut", + "Shoujo Ai", + "Yuri", + "4-koma", + "Mecha", + "Adult", + "Mature", + "Military", + "Vampire", + "Kids", + "Space", + "Police", + "Music", + "One Shot", + "Parody", + "Josei" + ) + ) + + private inline fun Iterable<*>.findInstance() = find { it is T } as? T + + private open class UriPartFilter(displayName: String, val vals: Array>) : + Filter.Select(displayName, vals.map { it.first }.toTypedArray()) { + fun toUriPart() = vals[state].second + } }