Split WPComics Extension (#5799)
* split WPComics * remove source, it was moved to wpmangastream * remove WPComics
|
@ -0,0 +1,75 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.en.comiclatest
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
|
||||||
|
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.SChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import org.jsoup.nodes.Element
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class ComicLatest : WPComics("ComicLatest", "https://comiclatest.com", "en", SimpleDateFormat("MM/dd/yyyy", Locale.US), null) {
|
||||||
|
// Hot only has one page
|
||||||
|
override val popularPath = "popular-comics"
|
||||||
|
|
||||||
|
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
|
||||||
|
element.select("h3 a").let {
|
||||||
|
title = it.text()
|
||||||
|
setUrlWithoutDomain(it.attr("href"))
|
||||||
|
}
|
||||||
|
thumbnail_url = element.select("img").attr("data-original")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
filters.forEach { filter ->
|
||||||
|
when (filter) {
|
||||||
|
is AuthorFilter -> {
|
||||||
|
val author = filter.state.trim().replace(" ", "-").toLowerCase()
|
||||||
|
return GET("$baseUrl/author/$author?page=$page", headers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GET("$baseUrl/search?keyword=$query&page=$page", headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun searchMangaSelector() = "div.item div.box_img > a[title]"
|
||||||
|
|
||||||
|
// For whatever reason, errors with author search if this isn't overridden
|
||||||
|
override fun searchMangaFromElement(element: Element): SManga {
|
||||||
|
return SManga.create().apply {
|
||||||
|
title = element.attr("title")
|
||||||
|
setUrlWithoutDomain(element.attr("href"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
|
val chapters = mutableListOf<SChapter>()
|
||||||
|
|
||||||
|
fun parseChapters(document: Document) {
|
||||||
|
document.select(chapterListSelector()).map { chapters.add(chapterFromElement(it)) }
|
||||||
|
document.select("ul.pagination a[rel=next]").firstOrNull()?.let { a ->
|
||||||
|
parseChapters(client.newCall(GET(a.attr("abs:href"), headers)).execute().asJsoup())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parseChapters(response.asJsoup())
|
||||||
|
return chapters
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pageListRequest(chapter: SChapter) = GET("$baseUrl${chapter.url}/all", headers)
|
||||||
|
|
||||||
|
private class AuthorFilter : Filter.Text("Author")
|
||||||
|
|
||||||
|
override fun getFilterList() = FilterList(
|
||||||
|
Filter.Header("NOTE: Cannot be used with search"),
|
||||||
|
Filter.Separator(),
|
||||||
|
AuthorFilter()
|
||||||
|
)
|
||||||
|
}
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 169 KiB |
|
@ -0,0 +1,31 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.all.mangasum
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
import eu.kanade.tachiyomi.source.SourceFactory
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
import okhttp3.Request
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class MangaSumFactory : SourceFactory {
|
||||||
|
override fun createSources(): List<Source> = listOf(
|
||||||
|
MangaSum(),
|
||||||
|
MangaSumRAW(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
class MangaSumRAW : WPComics("MangaSum RAW", "https://mangasum.com", "ja", SimpleDateFormat("MM/dd/yy", Locale.US), null) {
|
||||||
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
|
return GET("$baseUrl/raw" + if (page > 1) "?page=$page" else "", headers)
|
||||||
|
}
|
||||||
|
override fun popularMangaSelector() = "div.items div.item"
|
||||||
|
override fun latestUpdatesRequest(page: Int) = popularMangaRequest(page)
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/genres?keyword=$query&page=$page", headers)
|
||||||
|
override fun searchMangaSelector() = "div.items div.item div.image a[title*=' - Raw']"
|
||||||
|
}
|
||||||
|
|
||||||
|
class MangaSum : WPComics("MangaSum", "https://mangasum.com", "en", SimpleDateFormat("MM/dd/yy", Locale.US), null) {
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/genres?keyword=$query&page=$page", headers)
|
||||||
|
override fun searchMangaSelector() = "div.items div.item div.image a:not([title*=' - Raw'])"
|
||||||
|
}
|
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 101 KiB |
|
@ -0,0 +1,57 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.en.manhuaes
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import okhttp3.Request
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import org.jsoup.nodes.Element
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class ManhuaES : WPComics("Manhua ES", "https://manhuaes.com", "en", SimpleDateFormat("HH:mm - dd/MM/yyyy Z", Locale.US), "+0700") {
|
||||||
|
override val popularPath = "category-comics/manga"
|
||||||
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
|
return GET("$baseUrl/$popularPath" + if (page > 1) "/page/$page" else "", headers)
|
||||||
|
}
|
||||||
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
|
return GET(baseUrl + if (page > 1) "/page/$page" else "", headers)
|
||||||
|
}
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
return GET("$baseUrl/page/$page/?s=$query&post_type=comics")
|
||||||
|
}
|
||||||
|
override fun popularMangaNextPageSelector() = ".pagination li:last-child:not(.active)"
|
||||||
|
override fun popularMangaFromElement(element: Element): SManga {
|
||||||
|
return SManga.create().apply {
|
||||||
|
element.select("div.overlay a:has(h2)").let {
|
||||||
|
title = it.text()
|
||||||
|
setUrlWithoutDomain(it.attr("href"))
|
||||||
|
}
|
||||||
|
thumbnail_url = element.select("img").firstOrNull()?.attr("abs:src")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun mangaDetailsParse(document: Document): SManga {
|
||||||
|
return SManga.create().apply {
|
||||||
|
document.select("article#item-detail").let { info ->
|
||||||
|
author = info.select("li.author p.col-xs-8").text()
|
||||||
|
status = info.select("li.status p.col-xs-8").text().toStatus()
|
||||||
|
genre = info.select(".tags-genre a").joinToString { it.text() }
|
||||||
|
thumbnail_url = imageOrNull(info.select("div.col-image img").first())
|
||||||
|
|
||||||
|
val h3 = info.select(".detail-content h3").text()
|
||||||
|
val strong = info.select(".detail-content strong").text()
|
||||||
|
val showMoreFake = info.select(".detail-content .content-readmore").text()
|
||||||
|
val showMore = info.select(".detail-content .morelink").text()
|
||||||
|
val rawDesc = info.select("div.detail-content").text()
|
||||||
|
|
||||||
|
if (showMoreFake == null || showMoreFake == "") {
|
||||||
|
description = rawDesc.substringAfter(h3).substringAfter(strong).substringBefore(showMore)
|
||||||
|
} else {
|
||||||
|
description = rawDesc.substringAfter(h3).substringAfter(strong).substringBefore(showMoreFake)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override val pageListSelector = "div.chapter-detail ul img, div.chapter-detail div:not(.container) > img, div.chapter-detail p > img"
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.vi.nettruyen
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
|
import okhttp3.Request
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class NetTruyen : WPComics("NetTruyen", "http://www.nettruyen.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
|
||||||
|
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
|
||||||
|
override fun getFilterList(): FilterList {
|
||||||
|
return FilterList(
|
||||||
|
StatusFilter(getStatusList()),
|
||||||
|
GenreFilter(getGenreList())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.vi.nhattruyen
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
|
import okhttp3.Request
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class NhatTruyen : WPComics("NhatTruyen", "http://nhattruyen.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/the-loai?keyword=$query&page=$page", headers)
|
||||||
|
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.vi.truyenchon
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
|
import okhttp3.Request
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class TruyenChon : WPComics("TruyenChon", "http://truyenchon.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
|
||||||
|
override val searchPath = "the-loai"
|
||||||
|
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
|
||||||
|
override fun getFilterList(): FilterList {
|
||||||
|
return FilterList(
|
||||||
|
StatusFilter(getStatusList()),
|
||||||
|
GenreFilter(getGenreList())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.en.xoxocomics
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import org.jsoup.nodes.Element
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class XoxoComics : WPComics("XOXO Comics", "https://xoxocomics.com", "en", SimpleDateFormat("MM/dd/yy", Locale.US), null) {
|
||||||
|
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/comic-updates?page=$page", headers)
|
||||||
|
override fun latestUpdatesSelector() = "li.row"
|
||||||
|
override fun latestUpdatesFromElement(element: Element): SManga {
|
||||||
|
return SManga.create().apply {
|
||||||
|
element.select("h3 a").let {
|
||||||
|
title = it.text()
|
||||||
|
setUrlWithoutDomain(it.attr("href"))
|
||||||
|
}
|
||||||
|
thumbnail_url = element.select("img").attr("data-original")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
return GET("$baseUrl/search?keyword=$query&page=$page", headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
|
val chapters = mutableListOf<SChapter>()
|
||||||
|
|
||||||
|
// recursively add chapters from paginated chapter list
|
||||||
|
fun parseChapters(document: Document) {
|
||||||
|
document.select(chapterListSelector()).map { chapters.add(chapterFromElement(it)) }
|
||||||
|
document.select("ul.pagination a[rel=next]").firstOrNull()?.let { a ->
|
||||||
|
parseChapters(client.newCall(GET(a.attr("abs:href"), headers)).execute().asJsoup())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parseChapters(response.asJsoup())
|
||||||
|
return chapters
|
||||||
|
}
|
||||||
|
override fun pageListRequest(chapter: SChapter): Request = GET(baseUrl + "${chapter.url}/all")
|
||||||
|
}
|
|
@ -79,7 +79,6 @@ class MadaraGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("KlikManga", "https://klikmanga.com", "id"),
|
SingleLang("KlikManga", "https://klikmanga.com", "id"),
|
||||||
SingleLang("Kissmanga.in", "https://kissmanga.in", "en", className= "KissmangaIn"),
|
SingleLang("Kissmanga.in", "https://kissmanga.in", "en", className= "KissmangaIn"),
|
||||||
SingleLang("Kombatch", "https://kombatch.com", "id"),
|
SingleLang("Kombatch", "https://kombatch.com", "id"),
|
||||||
SingleLang("KomikGo", "https://komikgo.com", "id"),
|
|
||||||
SingleLang("Lily Manga", "https://lilymanga.com", "en"),
|
SingleLang("Lily Manga", "https://lilymanga.com", "en"),
|
||||||
SingleLang("LovableSubs", "https://lovablesubs.com", "tr"),
|
SingleLang("LovableSubs", "https://lovablesubs.com", "tr"),
|
||||||
SingleLang("Manga18 Fun", "https://manga18.fun", "en"),
|
SingleLang("Manga18 Fun", "https://manga18.fun", "en"),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package eu.kanade.tachiyomi.extension.all.wpcomics
|
package eu.kanade.tachiyomi.multisrc.wpcomics
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
|
@ -0,0 +1,31 @@
|
||||||
|
package eu.kanade.tachiyomi.multisrc.wpcomics
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.ThemeSourceData.SingleLang
|
||||||
|
import eu.kanade.tachiyomi.multisrc.ThemeSourceData.MultiLang
|
||||||
|
import eu.kanade.tachiyomi.multisrc.ThemeSourceGenerator
|
||||||
|
|
||||||
|
class WPComicsGenerator : ThemeSourceGenerator {
|
||||||
|
|
||||||
|
override val themePkg = "wpcomics"
|
||||||
|
|
||||||
|
override val themeClass = "WPComics"
|
||||||
|
|
||||||
|
override val baseVersionCode: Int = 1
|
||||||
|
|
||||||
|
override val sources = listOf(
|
||||||
|
SingleLang("ComicLatest", "https://comiclatest.com", "en"),
|
||||||
|
MultiLang("MangaSum", "https://mangasum.com", listOf("en", "ja")),
|
||||||
|
SingleLang("Manhua ES", "https://manhuaes.com", "en"),
|
||||||
|
SingleLang("NetTruyen", "http://www.nettruyen.com", "vi"),
|
||||||
|
SingleLang("NhatTruyen", "http://nhattruyen.com", "vi"),
|
||||||
|
SingleLang("TruyenChon", "http://truyenchon.com", "vi"),
|
||||||
|
SingleLang("XOXO Comics", "https://xoxocomics.com", "en", className = "XoxoComics"),
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
WPComicsGenerator().createAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest package="eu.kanade.tachiyomi.extension" />
|
|
|
@ -1,12 +0,0 @@
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
|
|
||||||
ext {
|
|
||||||
extName = 'WP-Comics'
|
|
||||||
pkgNameSuffix = 'all.wpcomics'
|
|
||||||
extClass = '.WPComicsFactory'
|
|
||||||
extVersionCode = 21
|
|
||||||
libVersion = '1.2'
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
|
@ -1,210 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.all.wpcomics
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import eu.kanade.tachiyomi.source.Source
|
|
||||||
import eu.kanade.tachiyomi.source.SourceFactory
|
|
||||||
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
|
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
import org.jsoup.nodes.Document
|
|
||||||
import org.jsoup.nodes.Element
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class WPComicsFactory : SourceFactory {
|
|
||||||
override fun createSources(): List<Source> = listOf(
|
|
||||||
ManhuaES(),
|
|
||||||
MangaSum(),
|
|
||||||
MangaSumRAW(),
|
|
||||||
XoxoComics(),
|
|
||||||
NhatTruyen(),
|
|
||||||
NetTruyen(),
|
|
||||||
TruyenChon(),
|
|
||||||
ComicLatest()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ManhuaES : WPComics("Manhua ES", "https://manhuaes.com", "en", SimpleDateFormat("HH:mm - dd/MM/yyyy Z", Locale.US), "+0700") {
|
|
||||||
override val popularPath = "category-comics/manga"
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
|
||||||
return GET("$baseUrl/$popularPath" + if (page > 1) "/page/$page" else "", headers)
|
|
||||||
}
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
|
||||||
return GET(baseUrl + if (page > 1) "/page/$page" else "", headers)
|
|
||||||
}
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
|
||||||
return GET("$baseUrl/page/$page/?s=$query&post_type=comics")
|
|
||||||
}
|
|
||||||
override fun popularMangaNextPageSelector() = ".pagination li:last-child:not(.active)"
|
|
||||||
override fun popularMangaFromElement(element: Element): SManga {
|
|
||||||
return SManga.create().apply {
|
|
||||||
element.select("div.overlay a:has(h2)").let {
|
|
||||||
title = it.text()
|
|
||||||
setUrlWithoutDomain(it.attr("href"))
|
|
||||||
}
|
|
||||||
thumbnail_url = element.select("img").firstOrNull()?.attr("abs:src")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
override fun mangaDetailsParse(document: Document): SManga {
|
|
||||||
return SManga.create().apply {
|
|
||||||
document.select("article#item-detail").let { info ->
|
|
||||||
author = info.select("li.author p.col-xs-8").text()
|
|
||||||
status = info.select("li.status p.col-xs-8").text().toStatus()
|
|
||||||
genre = info.select(".tags-genre a").joinToString { it.text() }
|
|
||||||
thumbnail_url = imageOrNull(info.select("div.col-image img").first())
|
|
||||||
|
|
||||||
val h3 = info.select(".detail-content h3").text()
|
|
||||||
val strong = info.select(".detail-content strong").text()
|
|
||||||
val showMoreFake = info.select(".detail-content .content-readmore").text()
|
|
||||||
val showMore = info.select(".detail-content .morelink").text()
|
|
||||||
val rawDesc = info.select("div.detail-content").text()
|
|
||||||
|
|
||||||
if (showMoreFake == null || showMoreFake == "") {
|
|
||||||
description = rawDesc.substringAfter(h3).substringAfter(strong).substringBefore(showMore)
|
|
||||||
} else {
|
|
||||||
description = rawDesc.substringAfter(h3).substringAfter(strong).substringBefore(showMoreFake)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
override val pageListSelector = "div.chapter-detail ul img, div.chapter-detail div:not(.container) > img, div.chapter-detail p > img"
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MangaSumRAW : WPComics("MangaSum RAW", "https://mangasum.com", "ja", SimpleDateFormat("MM/dd/yy", Locale.US), null) {
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
|
||||||
return GET("$baseUrl/raw" + if (page > 1) "?page=$page" else "", headers)
|
|
||||||
}
|
|
||||||
override fun popularMangaSelector() = "div.items div.item"
|
|
||||||
override fun latestUpdatesRequest(page: Int) = popularMangaRequest(page)
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/genres?keyword=$query&page=$page", headers)
|
|
||||||
override fun searchMangaSelector() = "div.items div.item div.image a[title*=' - Raw']"
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MangaSum : WPComics("MangaSum", "https://mangasum.com", "en", SimpleDateFormat("MM/dd/yy", Locale.US), null) {
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/genres?keyword=$query&page=$page", headers)
|
|
||||||
override fun searchMangaSelector() = "div.items div.item div.image a:not([title*=' - Raw'])"
|
|
||||||
}
|
|
||||||
|
|
||||||
private class XoxoComics : WPComics("XOXO Comics", "https://xoxocomics.com", "en", SimpleDateFormat("MM/dd/yy", Locale.US), null) {
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/comic-updates?page=$page", headers)
|
|
||||||
override fun latestUpdatesSelector() = "li.row"
|
|
||||||
override fun latestUpdatesFromElement(element: Element): SManga {
|
|
||||||
return SManga.create().apply {
|
|
||||||
element.select("h3 a").let {
|
|
||||||
title = it.text()
|
|
||||||
setUrlWithoutDomain(it.attr("href"))
|
|
||||||
}
|
|
||||||
thumbnail_url = element.select("img").attr("data-original")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
|
||||||
return GET("$baseUrl/search?keyword=$query&page=$page", headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
|
||||||
val chapters = mutableListOf<SChapter>()
|
|
||||||
|
|
||||||
// recursively add chapters from paginated chapter list
|
|
||||||
fun parseChapters(document: Document) {
|
|
||||||
document.select(chapterListSelector()).map { chapters.add(chapterFromElement(it)) }
|
|
||||||
document.select("ul.pagination a[rel=next]").firstOrNull()?.let { a ->
|
|
||||||
parseChapters(client.newCall(GET(a.attr("abs:href"), headers)).execute().asJsoup())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseChapters(response.asJsoup())
|
|
||||||
return chapters
|
|
||||||
}
|
|
||||||
override fun pageListRequest(chapter: SChapter): Request = GET(baseUrl + "${chapter.url}/all")
|
|
||||||
}
|
|
||||||
|
|
||||||
private class NhatTruyen : WPComics("NhatTruyen", "http://nhattruyen.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/the-loai?keyword=$query&page=$page", headers)
|
|
||||||
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
|
|
||||||
}
|
|
||||||
|
|
||||||
private class NetTruyen : WPComics("NetTruyen", "http://www.nettruyen.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
|
|
||||||
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
|
|
||||||
override fun getFilterList(): FilterList {
|
|
||||||
return FilterList(
|
|
||||||
StatusFilter(getStatusList()),
|
|
||||||
GenreFilter(getGenreList())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TruyenChon : WPComics("TruyenChon", "http://truyenchon.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
|
|
||||||
override val searchPath = "the-loai"
|
|
||||||
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
|
|
||||||
override fun getFilterList(): FilterList {
|
|
||||||
return FilterList(
|
|
||||||
StatusFilter(getStatusList()),
|
|
||||||
GenreFilter(getGenreList())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ComicLatest : WPComics("ComicLatest", "https://comiclatest.com", "en", SimpleDateFormat("MM/dd/yyyy", Locale.US), null) {
|
|
||||||
// Hot only has one page
|
|
||||||
override val popularPath = "popular-comics"
|
|
||||||
|
|
||||||
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
|
|
||||||
element.select("h3 a").let {
|
|
||||||
title = it.text()
|
|
||||||
setUrlWithoutDomain(it.attr("href"))
|
|
||||||
}
|
|
||||||
thumbnail_url = element.select("img").attr("data-original")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
|
||||||
filters.forEach { filter ->
|
|
||||||
when (filter) {
|
|
||||||
is AuthorFilter -> {
|
|
||||||
val author = filter.state.trim().replace(" ", "-").toLowerCase()
|
|
||||||
return GET("$baseUrl/author/$author?page=$page", headers)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GET("$baseUrl/search?keyword=$query&page=$page", headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun searchMangaSelector() = "div.item div.box_img > a[title]"
|
|
||||||
|
|
||||||
// For whatever reason, errors with author search if this isn't overridden
|
|
||||||
override fun searchMangaFromElement(element: Element): SManga {
|
|
||||||
return SManga.create().apply {
|
|
||||||
title = element.attr("title")
|
|
||||||
setUrlWithoutDomain(element.attr("href"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
|
||||||
val chapters = mutableListOf<SChapter>()
|
|
||||||
|
|
||||||
fun parseChapters(document: Document) {
|
|
||||||
document.select(chapterListSelector()).map { chapters.add(chapterFromElement(it)) }
|
|
||||||
document.select("ul.pagination a[rel=next]").firstOrNull()?.let { a ->
|
|
||||||
parseChapters(client.newCall(GET(a.attr("abs:href"), headers)).execute().asJsoup())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseChapters(response.asJsoup())
|
|
||||||
return chapters
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter) = GET("$baseUrl${chapter.url}/all", headers)
|
|
||||||
|
|
||||||
private class AuthorFilter : Filter.Text("Author")
|
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
|
||||||
Filter.Header("NOTE: Cannot be used with search"),
|
|
||||||
Filter.Separator(),
|
|
||||||
AuthorFilter()
|
|
||||||
)
|
|
||||||
}
|
|