diff --git a/src/all/fmreader/build.gradle b/src/all/fmreader/build.gradle index ccd52999f..2627dc684 100644 --- a/src/all/fmreader/build.gradle +++ b/src/all/fmreader/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'FMReader (multiple aggregators)' pkgNameSuffix = 'all.fmreader' extClass = '.FMReaderFactory' - extVersionCode = 24 + extVersionCode = 25 libVersion = '1.2' containsNsfw = true } diff --git a/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReader.kt b/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReader.kt index b0a85d2f1..d8ea97a32 100644 --- a/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReader.kt +++ b/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReader.kt @@ -48,6 +48,7 @@ abstract class FMReader( element == null -> null element.hasAttr("data-original") -> element.attr("abs:data-original") element.hasAttr("data-src") -> element.attr("abs:data-src") + element.hasAttr("data-bg") -> element.attr("abs:data-bg") else -> element.attr("abs:src") } } @@ -121,21 +122,21 @@ abstract class FMReader( override fun searchMangaParse(response: Response) = popularMangaParse(response) - override fun popularMangaSelector() = "div.media" + override fun popularMangaSelector() = "div.media, .thumb-item-flow" override fun latestUpdatesSelector() = popularMangaSelector() override fun searchMangaSelector() = popularMangaSelector() - open val headerSelector = "h3" + open val headerSelector = "h3 a, .series-title a" override fun popularMangaFromElement(element: Element): SManga { return SManga.create().apply { - element.select("$headerSelector a").let { + element.select("$headerSelector").let { setUrlWithoutDomain(it.attr("abs:href")) title = it.text() } - thumbnail_url = element.select("img").imgAttr() + thumbnail_url = element.select("img, .thumb-wrapper .img-in-ratio").imgAttr() } } @@ -148,7 +149,7 @@ abstract class FMReader( * one is an element with text "page x of y", must be the first element if it's part of a collection * the other choice is the standard "next page" element (but most FMReader sources don't have this one) */ - override fun popularMangaNextPageSelector() = "div.col-lg-9 button.btn-info" + override fun popularMangaNextPageSelector() = "div.col-lg-9 button.btn-info, .pagination a:contains(»):not(.disabled)" override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() @@ -161,7 +162,7 @@ abstract class FMReader( author = infoElement.select("li a.btn-info").text() genre = infoElement.select("li a.btn-danger").joinToString { it.text() } status = parseStatus(infoElement.select("li a.btn-success").first()?.text()) - description = document.select("div.detail .content, div.row ~ div.row:has(h3:first-child) p").text().trim() + description = document.select("div.detail .content, div.row ~ div.row:has(h3:first-child) p, .summary-content p").text().trim() thumbnail_url = infoElement.select("img.thumbnail").imgAttr() } } @@ -180,7 +181,7 @@ abstract class FMReader( override fun chapterListParse(response: Response): List { val document = response.asJsoup() - val mangaTitle = document.select(".manga-info h1").text() + val mangaTitle = document.select(".manga-info h1, .manga-info h3").text() return document.select(chapterListSelector()).map { chapterFromElement(it, mangaTitle) }.distinctBy { it.url } } @@ -188,17 +189,26 @@ abstract class FMReader( return chapterFromElement(element, "") } - override fun chapterListSelector() = "div#list-chapters p, table.table tr" + override fun chapterListSelector() = "div#list-chapters p, table.table tr, .list-chapters a" open val chapterUrlSelector = "a" - open val chapterTimeSelector = "time" + open val chapterTimeSelector = "time, .chapter-time" + + open val chapterNameAttrSelector = "title" open fun chapterFromElement(element: Element, mangaTitle: String = ""): SChapter { return SChapter.create().apply { - element.select(chapterUrlSelector).first().let { - setUrlWithoutDomain(it.attr("abs:href")) - name = it.text().substringAfter("$mangaTitle ") + if (chapterUrlSelector != "") { + element.select(chapterUrlSelector).first().let { + setUrlWithoutDomain(it.attr("abs:href")) + name = it.text().substringAfter("$mangaTitle ") + } + } else { + element.let { + setUrlWithoutDomain(it.attr("abs:href")) + name = element.attr(chapterNameAttrSelector).substringAfter("$mangaTitle ") + } } date_upload = element.select(chapterTimeSelector).let { if (it.hasText()) parseChapterDate(it.text()) else 0 } } @@ -210,7 +220,7 @@ abstract class FMReader( // gets the unit of time (day, week hour) from "1 day ago" open val dateWordIndex = 1 - open fun parseChapterDate(date: String): Long { + private fun parseChapterDate(date: String): Long { val value = date.split(' ')[dateValueIndex].toInt() val dateWord = date.split(' ')[dateWordIndex].let { if (it.contains("(")) { @@ -268,7 +278,10 @@ abstract class FMReader( protected fun base64PageListParse(document: Document): List { fun Element.decoded(): String { - val attr = if (this.hasAttr("data-original")) "data-original" else "data-src" + val attr = + if (this.hasAttr("data-original")) "data-original" + else if (this.hasAttr("data-src")) "data-src" + else "src" return if (!this.attr(attr).contains(".")) { Base64.decode(this.attr(attr), Base64.DEFAULT).toString(Charset.defaultCharset()) } else { diff --git a/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReaderFactory.kt b/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReaderFactory.kt index 3ad85fa19..345aaecfb 100644 --- a/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReaderFactory.kt +++ b/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReaderFactory.kt @@ -1,6 +1,5 @@ package eu.kanade.tachiyomi.extension.all.fmreader -import android.util.Base64 import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.asObservableSuccess @@ -19,7 +18,6 @@ import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element import rx.Observable -import java.nio.charset.Charset class FMReaderFactory : SourceFactory { override fun createSources(): List = listOf( @@ -45,7 +43,7 @@ class FMReaderFactory : SourceFactory { class LHTranslation : FMReader("LHTranslation", "https://lhtranslation.net", "en") -class KissLove : FMReader("KissLove", "https://kisslove.net", "ja") { +class KissLove : FMReader("KissLove", "https://kissaway.net", "ja") { override fun pageListParse(document: Document): List = base64PageListParse(document) } @@ -72,53 +70,8 @@ class HeroScan : FMReader("HeroScan", "https://heroscan.com", "en") { } class RawLH : FMReader("RawLH", "https://lovehug.net", "ja") { - override fun popularMangaSelector() = "#history .thumb-item-flow" - override fun popularMangaFromElement(element: Element): SManga { - return SManga.create().apply { - element.select(".series-title a").let { - setUrlWithoutDomain(it.attr("abs:href")) - title = it.text() - } - thumbnail_url = element.select(".thumb-wrapper .img-in-ratio").imgAttr() - } - } - override fun popularMangaNextPageSelector() = ".pagination a:contains(»):not(.disabled)" - override fun mangaDetailsParse(document: Document): SManga { - val infoElement = document.select("div.row").first() - - return SManga.create().apply { - author = infoElement.select("li a.btn-info").text() - genre = infoElement.select("li a.btn-danger").joinToString { it.text() } - status = parseStatus(infoElement.select("li a.btn-success").first()?.text()) - description = document.select(".summary-content p").text().trim() - thumbnail_url = infoElement.select(".thumbnail").imgAttr() - } - } - override fun chapterListSelector() = ".list-chapters a" - override fun chapterFromElement(element: Element, mangaTitle: String): SChapter { - return SChapter.create().apply { - element.let { - setUrlWithoutDomain(it.attr("abs:href")) - name = element.attr("title") - } - date_upload = element.select(".chapter-time").let { if (it.hasText()) parseChapterDate(it.text()) else 0 } - } - } - override fun pageListParse(document: Document): List = base64PageListParse2(document) - protected fun base64PageListParse2(document: Document): List { - fun Element.decoded(): String { - val attr = "src" - return if (!this.attr(attr).contains(".")) { - Base64.decode(this.attr(attr), Base64.DEFAULT).toString(Charset.defaultCharset()) - } else { - this.attr("abs:$attr") - } - } - - return document.select("img.chapter-img").mapIndexed { i, img -> - Page(i, document.location(), img.decoded()) - } - } + override val chapterUrlSelector = "" + override fun pageListParse(document: Document): List = base64PageListParse(document) // Referer needs to be chapter URL override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().set("Referer", page.url).build()) } @@ -282,7 +235,7 @@ class EpikManga : FMReader("Epik Manga", "https://www.epikmanga.com", "tr") { override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/seri-listesi?sorting=lastUpdate&sorting-type=DESC&Sayfa=$page", headers) override fun popularMangaNextPageSelector() = "ul.pagination li.active + li:not(.disabled)" - override val headerSelector = "h4" + override val headerSelector = "h4 a" // search wasn't working on source's website override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable {