feat: wnacg extension change (#9214)

1. code format
2. add category filter
3. manga detail add description parse
4. add nsfw
5. change extVersionCode
6. fix next page selector logic

Co-authored-by: John Bi <869384236@qq.com>
This commit is contained in:
John Bi 2021-09-25 18:20:08 +08:00 committed by GitHub
parent 7cc865e8fb
commit eacb84dbf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 6 deletions

View File

@ -5,7 +5,8 @@ ext {
extName = 'WNACG' extName = 'WNACG'
pkgNameSuffix = 'zh.wnacg' pkgNameSuffix = 'zh.wnacg'
extClass = '.wnacg' extClass = '.wnacg'
extVersionCode = 5 extVersionCode = 6
containsNsfw = true
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View File

@ -1,7 +1,11 @@
package eu.kanade.tachiyomi.extension.zh.wnacg package eu.kanade.tachiyomi.extension.zh.wnacg
import eu.kanade.tachiyomi.annotations.Nsfw
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
@ -12,7 +16,9 @@ import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable
@Nsfw
class wnacg : ParsedHttpSource() { class wnacg : ParsedHttpSource() {
override val name = "紳士漫畫" override val name = "紳士漫畫"
override val baseUrl = "https://www.wnacg.org" override val baseUrl = "https://www.wnacg.org"
@ -24,7 +30,7 @@ class wnacg : ParsedHttpSource() {
override fun searchMangaSelector() = popularMangaSelector() override fun searchMangaSelector() = popularMangaSelector()
override fun chapterListSelector() = "div.f_left > a" override fun chapterListSelector() = "div.f_left > a"
override fun popularMangaNextPageSelector() = "a:containsOwn(後頁)" override fun popularMangaNextPageSelector() = "span.thispage + a"
override fun latestUpdatesNextPageSelector() = throw Exception("Not used") override fun latestUpdatesNextPageSelector() = throw Exception("Not used")
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
@ -34,6 +40,30 @@ class wnacg : ParsedHttpSource() {
override fun latestUpdatesRequest(page: Int) = throw Exception("Not used") override fun latestUpdatesRequest(page: Int) = throw Exception("Not used")
override fun fetchSearchManga(
page: Int,
query: String,
filters: FilterList
): Observable<MangasPage> {
// ps: this web don't support category search and sort
var req: Request? = null
if (query.isNotBlank()) {
req = this.searchMangaRequest(page, query, filters)
} else if (filters.isNotEmpty()) {
filters.forEach { filter ->
if (filter is CategoryFilter) {
req = GET("$baseUrl/" + filter.toUriPart().format(page))
}
}
}
if (req != null) {
return client.newCall(req!!)
.asObservableSuccess()
.map { response -> queryParse(response) }
}
return super.fetchSearchManga(page, query, filters)
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return GET("$baseUrl/search/index.php?q=$query&p=$page", headers) return GET("$baseUrl/search/index.php?q=$query&p=$page", headers)
} }
@ -46,7 +76,10 @@ class wnacg : ParsedHttpSource() {
.set("referer", baseUrl) .set("referer", baseUrl)
.set("sec-fetch-mode", "no-cors") .set("sec-fetch-mode", "no-cors")
.set("sec-fetch-site", "cross-site") .set("sec-fetch-site", "cross-site")
.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36") .set(
"User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
)
override fun popularMangaFromElement(element: Element) = mangaFromElement(element) override fun popularMangaFromElement(element: Element) = mangaFromElement(element)
override fun latestUpdatesFromElement(element: Element) = throw Exception("Not used") override fun latestUpdatesFromElement(element: Element) = throw Exception("Not used")
@ -63,6 +96,14 @@ class wnacg : ParsedHttpSource() {
return manga return manga
} }
private fun queryParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangas = document.select(searchMangaSelector())
.map { element -> searchMangaFromElement(element) }
val nextPage = document.select(searchMangaNextPageSelector()).first() != null
return MangasPage(mangas, nextPage)
}
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup() val document = response.asJsoup()
val chapters = mutableListOf<SChapter>() val chapters = mutableListOf<SChapter>()
@ -83,14 +124,25 @@ class wnacg : ParsedHttpSource() {
manga.title = document.select("h2")?.text()?.trim() ?: "Unknown" manga.title = document.select("h2")?.text()?.trim() ?: "Unknown"
manga.artist = document.select("div.uwuinfo p")?.first()?.text()?.trim() ?: "Unknown" manga.artist = document.select("div.uwuinfo p")?.first()?.text()?.trim() ?: "Unknown"
manga.author = document.select("div.uwuinfo p")?.first()?.text()?.trim() ?: "Unknown" manga.author = document.select("div.uwuinfo p")?.first()?.text()?.trim() ?: "Unknown"
manga.thumbnail_url = "https://" + document.select("div.uwthumb img").first().attr("src").replace("//", "") manga.thumbnail_url =
"https://" + document.select("div.uwthumb img").first().attr("src").replace("//", "")
manga.description =
document.select("div.asTBcell p")?.first()?.html()?.replace("<br>", "\n")
return manga return manga
} }
override fun pageListParse(document: Document): List<Page> { override fun pageListParse(document: Document): List<Page> {
val regex = "\\/\\/\\S*(jpg|png)".toRegex() val regex = "\\/\\/\\S*(jpg|png)".toRegex()
val slideaid = client.newCall(GET(baseUrl + document.select("a.btn:containsOwn(下拉閱讀)").attr("href"), headers)).execute().asJsoup() val slideaid = client.newCall(
val galleryaid = client.newCall(GET(baseUrl + slideaid.select("script[src$=html]").attr("src"), headers)).execute().asJsoup().toString() GET(
baseUrl + document.select("a.btn:containsOwn(下拉閱讀)").attr("href"),
headers
)
).execute().asJsoup()
val galleryaid =
client.newCall(GET(baseUrl + slideaid.select("script[src$=html]").attr("src"), headers))
.execute().asJsoup().toString()
val matchresult = regex.findAll(galleryaid).map { it.value }.toList() val matchresult = regex.findAll(galleryaid).map { it.value }.toList()
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
for (i in matchresult.indices) { for (i in matchresult.indices) {
@ -102,4 +154,35 @@ class wnacg : ParsedHttpSource() {
override fun chapterFromElement(element: Element) = throw Exception("Not used") override fun chapterFromElement(element: Element) = throw Exception("Not used")
override fun imageUrlRequest(page: Page) = throw Exception("Not used") override fun imageUrlRequest(page: Page) = throw Exception("Not used")
override fun imageUrlParse(document: Document) = throw Exception("Not used") override fun imageUrlParse(document: Document) = throw Exception("Not used")
// >>> Filters >>>
override fun getFilterList() = FilterList(
Filter.Header("注意:分类不支持搜索"),
CategoryFilter()
)
private class CategoryFilter : UriPartFilter(
"分类",
arrayOf(
Pair("更新", "albums-index-page-%d.html"),
Pair("同人志-汉化", "albums-index-page-%d-cate-1.html"),
Pair("同人志-日语", "albums-index-page-%d-cate-12.html"),
Pair("同人志-CG书籍", "albums-index-page-%d-cate-2.html"),
Pair("同人志-Cosplay", "albums-index-page-%d-cate-3.html"),
Pair("单行本-汉化", "albums-index-page-%d-cate-9.html"),
Pair("单行本-日语", "albums-index-page-%d-cate-13.html"),
Pair("杂志&短篇-汉语", "albums-index-page-%d-cate-10.html"),
Pair("杂志&短篇-日语", "albums-index-page-%d-cate-14.html"),
Pair("韩漫-汉化", "albums-index-page-%d-cate-20.html"),
Pair("韩漫-生肉", "albums-index-page-%d-cate-21.html"),
)
)
private open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>) :
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
fun toUriPart() = vals[state].second
}
// <<< Filters <<<
} }