diff --git a/src/zh/wuqimanga/build.gradle b/src/zh/wuqimanga/build.gradle new file mode 100644 index 000000000..41de359ce --- /dev/null +++ b/src/zh/wuqimanga/build.gradle @@ -0,0 +1,18 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +ext { + appName = 'Tachiyomi: WuqiManga' + pkgNameSuffix = 'zh.wuqimanga' + extClass = '.WuqiManga' + extVersionCode = 1 + libVersion = '1.2' +} + +dependencies { + compileOnly project(':duktape-stub') + compileOnly 'com.google.code.gson:gson:2.8.2' + compileOnly 'com.github.salomonbrys.kotson:kotson:2.5.0' +} + +apply from: "$rootDir/common.gradle" diff --git a/src/zh/wuqimanga/res/mipmap-hdpi/ic_launcher.png b/src/zh/wuqimanga/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..90438cd32 Binary files /dev/null and b/src/zh/wuqimanga/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/zh/wuqimanga/res/mipmap-mdpi/ic_launcher.png b/src/zh/wuqimanga/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..8363d3ff0 Binary files /dev/null and b/src/zh/wuqimanga/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/zh/wuqimanga/res/mipmap-xhdpi/ic_launcher.png b/src/zh/wuqimanga/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..9d08867db Binary files /dev/null and b/src/zh/wuqimanga/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/zh/wuqimanga/res/mipmap-xxhdpi/ic_launcher.png b/src/zh/wuqimanga/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..e5401866f Binary files /dev/null and b/src/zh/wuqimanga/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/zh/wuqimanga/res/mipmap-xxxhdpi/ic_launcher.png b/src/zh/wuqimanga/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..a3fe98e29 Binary files /dev/null and b/src/zh/wuqimanga/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/zh/wuqimanga/res/web_hi_res_512.png b/src/zh/wuqimanga/res/web_hi_res_512.png new file mode 100644 index 000000000..975429ec4 Binary files /dev/null and b/src/zh/wuqimanga/res/web_hi_res_512.png differ diff --git a/src/zh/wuqimanga/src/eu/kanade/tachiyomi/extension/zh/wuqimanga/Comic.kt b/src/zh/wuqimanga/src/eu/kanade/tachiyomi/extension/zh/wuqimanga/Comic.kt new file mode 100644 index 000000000..2aff8e3c5 --- /dev/null +++ b/src/zh/wuqimanga/src/eu/kanade/tachiyomi/extension/zh/wuqimanga/Comic.kt @@ -0,0 +1,7 @@ +package eu.kanade.tachiyomi.extension.zh.wuqimanga + +class Comic { + + val fs: List? = listOf() + +} diff --git a/src/zh/wuqimanga/src/eu/kanade/tachiyomi/extension/zh/wuqimanga/WuqiManga.kt b/src/zh/wuqimanga/src/eu/kanade/tachiyomi/extension/zh/wuqimanga/WuqiManga.kt new file mode 100644 index 000000000..2a6efe44d --- /dev/null +++ b/src/zh/wuqimanga/src/eu/kanade/tachiyomi/extension/zh/wuqimanga/WuqiManga.kt @@ -0,0 +1,160 @@ +package eu.kanade.tachiyomi.extension.zh.wuqimanga + +import android.util.Log +import com.google.gson.Gson +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.model.* +import eu.kanade.tachiyomi.source.online.ParsedHttpSource +import eu.kanade.tachiyomi.util.asJsoup +import okhttp3.Headers +import okhttp3.Request +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import com.squareup.duktape.Duktape + +class WuqiManga : ParsedHttpSource() { + + override val name = "57漫画" + override val baseUrl = "http://www.wuqimh.com" + override val lang = "zh" + override val supportsLatest = false + private val imageServer = "http://images.lancaier.com" + + override fun latestUpdatesRequest(page: Int) = throw Exception("Not used") + override fun latestUpdatesNextPageSelector() = throw Exception("Not used") + override fun latestUpdatesSelector() = throw Exception("Not used") + override fun latestUpdatesFromElement(element: Element) = throw Exception("Not used") + + override fun popularMangaRequest(page: Int) = GET("$baseUrl/list/area-日本-order-hits", headers) + override fun popularMangaSelector() = "ul#contList > li" + override fun popularMangaNextPageSelector(): String? = null + + override fun popularMangaFromElement(element: Element): SManga { + val coverEl = element.select("a img").first() + val cover = if (coverEl.hasAttr("data-src")) { + coverEl.attr("data-src") + } else { + coverEl.attr("src") + } + val title = element.select("a").attr("title") + val url = element.select("a").attr("href") + + val manga = SManga.create() + + manga.thumbnail_url = cover + manga.title = title + manga.url = url + + return manga + } + + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + return GET("$baseUrl/search/q_$query-p-$page", headers) + } + + override fun searchMangaNextPageSelector() = "div.book-result > div > span > a.prev" + override fun searchMangaSelector() = "div.book-result li.cf" + override fun searchMangaFromElement(element: Element): SManga { + val manga = SManga.create() + element.select("div.book-detail").first().let { + val titleEl = it.select("dl > dt > a") + manga.setUrlWithoutDomain(titleEl.attr("href")) + manga.title = titleEl.attr("title").trim() + manga.description = it.select("dd.intro").text() + val status = it.select("dd.tags.status") + manga.status = if (status.select("span.red").first().text().contains("连载中")) { + SManga.ONGOING + } else { + SManga.COMPLETED + } + for (el in it.select("dd.tags")) { + if (el.select("span strong").text().contains("作者")) { + manga.author = el.select("span a").text() + } + } + } + manga.thumbnail_url = element.select("a.bcover > img").attr("src") + return manga + } + + override fun mangaDetailsRequest(manga: SManga) = GET("$baseUrl/${manga.url}", headers) + override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga) + override fun chapterListSelector() = throw Exception("Not used") + + override fun pageListRequest(chapter: SChapter) = GET("$baseUrl/${chapter.url}", headers) + + + override fun headersBuilder() = Headers.Builder().add("Referer", "$baseUrl/") + .set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36") + + + override fun chapterFromElement(element: Element): SChapter { + val urlElement = element.select("a") + + val chapter = SChapter.create() + chapter.url = urlElement.attr("href") + chapter.name = urlElement.attr("alt").trim() + return chapter + } + + override fun mangaDetailsParse(document: Document): SManga { + val manga = SManga.create() + manga.description = "" + manga.title = document.select(".book-title h1").text().trim() + manga.thumbnail_url = document.select(".hcover img").attr("src") + for (element in document.select("ul.detail-list li span")) { + if (element.select("strong").text().contains("漫画作者")) { + manga.author = element.select("a").text() + break + } + } + return manga + } + + override fun imageRequest(page: Page): Request { + return GET(page.imageUrl.toString(), headers) + } + + override fun imageUrlRequest(page: Page): Request { + return GET(page.imageUrl.toString(), headers) + } + + override fun imageUrlParse(document: Document): String = "" + + + override fun chapterListParse(response: Response): List { + val chapters = mutableListOf() + response.asJsoup().select("div.chapter div.chapter-list>ul").asReversed().forEach { + it.select("li a").forEach { + chapters.add(SChapter.create().apply { + url = it.attr("href") + name = it.attr("title") + }) + } + } + return chapters + } + + private val gson = Gson() + + override fun pageListParse(document: Document): List { + val html = document.html() + val packed = Regex("eval(.*?)\\n").find(html)?.groups?.get(1)?.value + val result = Duktape.create().use { + it.evaluate(packed) as String + } + val re2 = Regex("""\{.*\}""") + val imgJsonStr = re2.find(result)?.groups?.get(0)?.value + val imageJson: Comic = gson.fromJson(imgJsonStr, Comic::class.java) + + return imageJson.fs!!.mapIndexed { i, imgStr -> + val imgurl = "$imageServer$imgStr" + Page(i, "", imgurl) + } + } + + override fun getFilterList() = FilterList() + +}