FMReader - add SayTruyen (#2632)
* FMReader - add SayTruyen * Update build.gradle
This commit is contained in:
parent
bee6c44417
commit
5de4e42929
@ -5,7 +5,7 @@ ext {
|
|||||||
appName = 'Tachiyomi: FMReader (multiple aggregators)'
|
appName = 'Tachiyomi: FMReader (multiple aggregators)'
|
||||||
pkgNameSuffix = 'all.fmreader'
|
pkgNameSuffix = 'all.fmreader'
|
||||||
extClass = '.FMReaderFactory'
|
extClass = '.FMReaderFactory'
|
||||||
extVersionCode = 7
|
extVersionCode = 8
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ abstract class FMReader(
|
|||||||
override val client: OkHttpClient = network.cloudflareClient
|
override val client: OkHttpClient = network.cloudflareClient
|
||||||
|
|
||||||
override fun headersBuilder() = Headers.Builder().apply {
|
override fun headersBuilder() = Headers.Builder().apply {
|
||||||
add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64) Gecko/20100101 Firefox/69.0")
|
add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64) Gecko/20100101 Firefox/75.0")
|
||||||
add("Referer", baseUrl)
|
add("Referer", baseUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,9 +65,9 @@ abstract class FMReader(
|
|||||||
url.addQueryParameter("ungenre", ungenre)
|
url.addQueryParameter("ungenre", ungenre)
|
||||||
}
|
}
|
||||||
is SortBy -> {
|
is SortBy -> {
|
||||||
url.addQueryParameter("sort", when {
|
url.addQueryParameter("sort", when (filter.state?.index) {
|
||||||
filter.state?.index == 0 -> "name"
|
0 -> "name"
|
||||||
filter.state?.index == 1 -> "views"
|
1 -> "views"
|
||||||
else -> "last_update"
|
else -> "last_update"
|
||||||
})
|
})
|
||||||
if (filter.state?.ascending == true)
|
if (filter.state?.ascending == true)
|
||||||
@ -109,21 +109,15 @@ abstract class FMReader(
|
|||||||
override fun searchMangaSelector() = popularMangaSelector()
|
override fun searchMangaSelector() = popularMangaSelector()
|
||||||
|
|
||||||
override fun popularMangaFromElement(element: Element): SManga {
|
override fun popularMangaFromElement(element: Element): SManga {
|
||||||
val manga = SManga.create()
|
return SManga.create().apply {
|
||||||
|
|
||||||
element.select("h3 a").let {
|
element.select("h3 a").let {
|
||||||
manga.setUrlWithoutDomain(it.attr("abs:href"))
|
setUrlWithoutDomain(it.attr("abs:href"))
|
||||||
manga.title = it.text()
|
title = it.text()
|
||||||
}
|
}
|
||||||
manga.thumbnail_url = element.select("img").let {
|
thumbnail_url = element.select("img").let {
|
||||||
if (it.hasAttr("src")) {
|
if (it.hasAttr("src")) it.attr("abs:src") else it.attr("abs:data-original")
|
||||||
it.attr("abs:src")
|
|
||||||
} else {
|
|
||||||
it.attr("abs:data-original")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return manga
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
|
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
|
||||||
@ -142,24 +136,28 @@ abstract class FMReader(
|
|||||||
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
|
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document): SManga {
|
override fun mangaDetailsParse(document: Document): SManga {
|
||||||
val manga = SManga.create()
|
|
||||||
val infoElement = document.select("div.row").first()
|
val infoElement = document.select("div.row").first()
|
||||||
|
|
||||||
manga.author = infoElement.select("li a.btn-info").text()
|
return SManga.create().apply {
|
||||||
manga.genre = infoElement.select("li a.btn-danger").joinToString { it.text() }
|
author = infoElement.select("li a.btn-info").text()
|
||||||
manga.status = parseStatus(infoElement.select("li a.btn-success").first().text())
|
genre = infoElement.select("li a.btn-danger").joinToString { it.text() }
|
||||||
manga.description = document.select("div.row ~ div.row p").text().trim()
|
status = parseStatus(infoElement.select("li a.btn-success").first()?.text())
|
||||||
manga.thumbnail_url = infoElement.select("img.thumbnail").attr("abs:src")
|
description = document.select("div.row ~ div.row p").text().trim()
|
||||||
|
thumbnail_url = infoElement.select("img.thumbnail").attr("abs:src")
|
||||||
return manga
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// languages: en, vi, tr
|
// languages: en, vi, tr
|
||||||
fun parseStatus(status: String): Int = when (status.toLowerCase()) {
|
fun parseStatus(status: String?): Int {
|
||||||
"completed", "complete", "incomplete", "đã hoàn thành", "tamamlandı" -> SManga.COMPLETED
|
val completedWords = setOf("completed", "complete", "incomplete", "đã hoàn thành", "tamamlandı", "hoàn thành")
|
||||||
"ongoing", "on going", "updating", "chưa hoàn thành", "đang cập nhật", "devam ediyor" -> SManga.ONGOING
|
val ongoingWords = setOf("ongoing", "on going", "updating", "chưa hoàn thành", "đang cập nhật", "devam ediyor", "Đang tiến hành")
|
||||||
|
return when {
|
||||||
|
status == null -> SManga.UNKNOWN
|
||||||
|
completedWords.any { it.equals(status, ignoreCase = true) } -> SManga.COMPLETED
|
||||||
|
ongoingWords.any { it.equals(status, ignoreCase = true) } -> SManga.ONGOING
|
||||||
else -> SManga.UNKNOWN
|
else -> SManga.UNKNOWN
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun chapterListSelector() = "div#list-chapters p, table.table tr"
|
override fun chapterListSelector() = "div#list-chapters p, table.table tr"
|
||||||
|
|
||||||
@ -168,15 +166,13 @@ abstract class FMReader(
|
|||||||
open val chapterTimeSelector = "time"
|
open val chapterTimeSelector = "time"
|
||||||
|
|
||||||
override fun chapterFromElement(element: Element): SChapter {
|
override fun chapterFromElement(element: Element): SChapter {
|
||||||
val chapter = SChapter.create()
|
return SChapter.create().apply {
|
||||||
|
|
||||||
element.select(chapterUrlSelector).first().let {
|
element.select(chapterUrlSelector).first().let {
|
||||||
chapter.setUrlWithoutDomain(it.attr("abs:href"))
|
setUrlWithoutDomain(it.attr("abs:href"))
|
||||||
chapter.name = it.text()
|
name = it.text()
|
||||||
|
}
|
||||||
|
date_upload = element.select(chapterTimeSelector).let { if (it.hasText()) parseChapterDate(it.text()) else 0 }
|
||||||
}
|
}
|
||||||
chapter.date_upload = element.select(chapterTimeSelector).let { if (it.hasText()) parseChapterDate(it.text()) else 0 }
|
|
||||||
|
|
||||||
return chapter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets the number from "1 day ago"
|
// gets the number from "1 day ago"
|
||||||
|
@ -30,7 +30,6 @@ class FMReaderFactory : SourceFactory {
|
|||||||
MangaTiki(),
|
MangaTiki(),
|
||||||
MangaBone(),
|
MangaBone(),
|
||||||
YoloManga(),
|
YoloManga(),
|
||||||
AiLoveManga(),
|
|
||||||
ReadComicOnlineOrg(),
|
ReadComicOnlineOrg(),
|
||||||
HanaScan(),
|
HanaScan(),
|
||||||
RawLH(),
|
RawLH(),
|
||||||
@ -41,7 +40,8 @@ class FMReaderFactory : SourceFactory {
|
|||||||
Comicastle(),
|
Comicastle(),
|
||||||
Manhwa18Net(),
|
Manhwa18Net(),
|
||||||
Manhwa18NetRaw(),
|
Manhwa18NetRaw(),
|
||||||
MangaBorn()
|
MangaBorn(),
|
||||||
|
SayTruyen()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,30 +58,6 @@ class YoloManga : FMReader("Yolo Manga", "https://yolomanga.ca", "es") {
|
|||||||
override fun chapterListSelector() = "div#tab-chapper ~ div#tab-chapper table tr"
|
override fun chapterListSelector() = "div#tab-chapper ~ div#tab-chapper table tr"
|
||||||
}
|
}
|
||||||
|
|
||||||
class AiLoveManga : FMReader("AiLoveManga", "https://ailovemanga.com", "vi") {
|
|
||||||
override val requestPath = "danh-sach-truyen.html"
|
|
||||||
// TODO: could add a genre search (different URL paths for genres)
|
|
||||||
override fun getFilterList() = FilterList()
|
|
||||||
|
|
||||||
// I don't know why, but I have to override searchMangaRequest to make it work for this source
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/$requestPath?name=$query&page=$page")
|
|
||||||
|
|
||||||
override fun chapterListSelector() = "div#tab-chapper table tr"
|
|
||||||
override fun mangaDetailsParse(document: Document): SManga {
|
|
||||||
val manga = SManga.create()
|
|
||||||
val infoElement = document.select("div.container:has(img)").first()
|
|
||||||
|
|
||||||
manga.author = infoElement.select("a.btn-info").first().text()
|
|
||||||
manga.artist = infoElement.select("a.btn-info + a").text()
|
|
||||||
manga.genre = infoElement.select("a.btn-danger").joinToString { it.text() }
|
|
||||||
manga.status = parseStatus(infoElement.select("a.btn-success").text())
|
|
||||||
manga.description = document.select("div.col-sm-8 p").text().trim()
|
|
||||||
manga.thumbnail_url = infoElement.select("img").attr("abs:src")
|
|
||||||
|
|
||||||
return manga
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ReadComicOnlineOrg : FMReader("ReadComicOnline.org", "https://readcomiconline.org", "en") {
|
class ReadComicOnlineOrg : FMReader("ReadComicOnline.org", "https://readcomiconline.org", "en") {
|
||||||
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
||||||
.addInterceptor { requestIntercept(it) }
|
.addInterceptor { requestIntercept(it) }
|
||||||
@ -337,3 +313,24 @@ class MangaBorn : FMReader("MangaBorn", "https://hellxlight.com", "en") {
|
|||||||
override val pageListImageSelector = "div.panel-read-story img"
|
override val pageListImageSelector = "div.panel-read-story img"
|
||||||
override fun getFilterList() = FilterList()
|
override fun getFilterList() = FilterList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SayTruyen : FMReader("Say Truyen", "https://saytruyen.com", "vi") {
|
||||||
|
override fun mangaDetailsParse(document: Document): SManga {
|
||||||
|
val info = document.select("div.row").first()
|
||||||
|
return SManga.create().apply {
|
||||||
|
author = info.select("div.row li:has(b:contains(Tác giả)) small").text()
|
||||||
|
genre = info.select("div.row li:has(b:contains(Thể loại)) small a").joinToString { it.text() }
|
||||||
|
status = parseStatus(info.select("div.row li:has(b:contains(Tình trạng)) a").text())
|
||||||
|
description = document.select("div.description").text()
|
||||||
|
thumbnail_url = info.select("img.thumbnail").attr("abs:src")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
|
return response.asJsoup().let { document ->
|
||||||
|
document.select(chapterListSelector()).map { chapterFromElement(it).apply {
|
||||||
|
scanlator = document.select("div.row li:has(b:contains(Nhóm dịch)) small").text()
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun pageListParse(document: Document): List<Page> = super.pageListParse(document).onEach { it.imageUrl!!.trim() }
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user