From e8b8a9e51589d13b036db2586f2455f5ec18d4e1 Mon Sep 17 00:00:00 2001 From: Eugene Date: Wed, 20 Mar 2019 20:20:35 -0400 Subject: [PATCH] NHentai: fetch thumbnails directly from page response, add version to user agent (#953) NHentai: fetch thumbnails directly from page response, add version to user agent --- src/all/nhentai/build.gradle | 2 +- .../extension/all/nhentai/NHentai.kt | 131 ++++++++---------- 2 files changed, 56 insertions(+), 77 deletions(-) diff --git a/src/all/nhentai/build.gradle b/src/all/nhentai/build.gradle index ae4702c48..533dc95c4 100644 --- a/src/all/nhentai/build.gradle +++ b/src/all/nhentai/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: NHentai' pkgNameSuffix = 'all.nhentai' extClass = '.NHEnglish; .NHJapanese; .NHChinese' - extVersionCode = 7 + extVersionCode = 8 libVersion = '1.2' } diff --git a/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHentai.kt b/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHentai.kt index 5aa99a322..8cc05f50c 100644 --- a/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHentai.kt +++ b/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHentai.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.extension.all.nhentai +import eu.kanade.tachiyomi.extension.BuildConfig import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getArtists import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getGroups import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getTags @@ -12,73 +13,66 @@ import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.util.asJsoup import okhttp3.Headers -import okhttp3.MediaType +import okhttp3.HttpUrl import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response -import okhttp3.ResponseBody import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import java.net.URLEncoder open class NHentai(override val lang: String, private val nhLang: String) : ParsedHttpSource() { final override val baseUrl = "https://nhentai.net" + override val name = "NHentai" + override val supportsLatest = true - override val client: OkHttpClient = network.cloudflareClient.newBuilder().addInterceptor { chain -> - val url = chain.request().url().toString() - - // Artificial delay for images (aka ghetto throttling) - if (url.contains("i.nh")) { - Thread.sleep(250) - } - - chain.proceed(chain.request()) - }.build() + override val client: OkHttpClient = network.cloudflareClient override fun headersBuilder() = Headers.Builder().apply { - add("User-Agent", "Tachiyomi ${System.getProperty("http.agent")}") + add("User-Agent", "Tachiyomi/${BuildConfig.VERSION_NAME} ${System.getProperty("http.agent")}") } - private val searchUrl = "$baseUrl/search" + override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/language/$nhLang/?page=$page", headers) - override fun chapterFromElement(element: Element) = throw UnsupportedOperationException("Not used") - - override fun chapterListParse(response: Response): List { - val document = response.asJsoup() - val chapterList = mutableListOf() - val chapter = SChapter.create().apply { - name = "Chapter" - scanlator = getGroups(document) - date_upload = getTime(document) - setUrlWithoutDomain(response.request().url().encodedPath()) - } - - chapterList.add(chapter) - - return chapterList - } - - override fun chapterListRequest(manga: SManga): Request = GET("$baseUrl${manga.url}", headers) - - override fun chapterListSelector() = throw UnsupportedOperationException("Not used") - - override fun getFilterList(): FilterList = FilterList(SortFilter()) - - override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used") + override fun latestUpdatesSelector() = "#content .gallery" override fun latestUpdatesFromElement(element: Element) = SManga.create().apply { setUrlWithoutDomain(element.select("a").attr("href")) title = element.select("a > div").text().replace("\"", "").trim() + thumbnail_url = element.select(".cover img").attr("data-src") } override fun latestUpdatesNextPageSelector() = "#content > section.pagination > a.next" - override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/language/$nhLang/?page=$page", headers) + override fun popularMangaRequest(page: Int) = GET("$baseUrl/language/$nhLang/popular?page=$page", headers) - override fun latestUpdatesSelector() = "#content > div > div" + override fun popularMangaFromElement(element: Element) = latestUpdatesFromElement(element) + + override fun popularMangaSelector() = latestUpdatesSelector() + + override fun popularMangaNextPageSelector() = latestUpdatesNextPageSelector() + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() + .addQueryParameter("q", "$query +$nhLang") + .addQueryParameter("page", page.toString()) + + filters.forEach { + when (it) { + is SortFilter -> url.addQueryParameter("sort", it.values[it.state].toLowerCase()) + } + } + + return GET(url.build().toString(), headers) + } + + override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element) + + override fun searchMangaSelector() = latestUpdatesSelector() + + override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector() override fun mangaDetailsParse(document: Document) = SManga.create().apply { title = document.select("#info > h1").text().replace("\"", "").trim() @@ -89,6 +83,24 @@ open class NHentai(override val lang: String, private val nhLang: String) : Pars description = getTags(document) } + override fun chapterListRequest(manga: SManga): Request = GET("$baseUrl${manga.url}", headers) + + override fun chapterListParse(response: Response): List { + val document = response.asJsoup() + return listOf(SChapter.create().apply { + name = "Chapter" + scanlator = getGroups(document) + date_upload = getTime(document) + setUrlWithoutDomain(response.request().url().encodedPath()) + }) + } + + override fun chapterFromElement(element: Element) = throw UnsupportedOperationException("Not used") + + override fun chapterListSelector() = throw UnsupportedOperationException("Not used") + + override fun pageListRequest(chapter: SChapter) = GET("$baseUrl${chapter.url}", headers) + override fun pageListParse(document: Document): List { val pageElements = document.select("#thumbnail-container > div") val pageList = mutableListOf() @@ -104,41 +116,8 @@ open class NHentai(override val lang: String, private val nhLang: String) : Pars return pageList } - override fun pageListRequest(chapter: SChapter) = GET("$baseUrl${chapter.url}", headers) + override fun getFilterList(): FilterList = FilterList(SortFilter()) - override fun popularMangaFromElement(element: Element) = SManga.create().apply { - setUrlWithoutDomain(element.select("a").attr("href")) - title = element.select("a > div").text().replace("\"", "").trim() - } + override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used") - override fun popularMangaNextPageSelector() = "#content > section.pagination > a.next" - - override fun popularMangaRequest(page: Int) = GET("$baseUrl/language/$nhLang/popular?page=$page", headers) - - override fun popularMangaSelector() = "#content > div > div" - - override fun searchMangaFromElement(element: Element) = SManga.create().apply { - setUrlWithoutDomain(element.select("a").attr("href")) - title = element.select("a > div").text().replace("\"", "").trim() - } - - override fun searchMangaNextPageSelector() = "#content > section.pagination > a.next" - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val stringBuilder = StringBuilder() - stringBuilder.append(searchUrl) - stringBuilder.append("/?q=${URLEncoder.encode("$query +$nhLang", "UTF-8")}&") - - filters.forEach { - when (it) { - is SortFilter -> stringBuilder.append("sort=${it.values[it.state].toLowerCase()}&") - } - } - - stringBuilder.append("page=$page") - - return GET(stringBuilder.toString(), headers) - } - - override fun searchMangaSelector() = "#content > div > div" }