From 0e446fb7d07a2561a17dc92e80f03e8e0dcfd886 Mon Sep 17 00:00:00 2001 From: yshui Date: Sun, 5 May 2019 22:14:24 +0100 Subject: [PATCH] manhuaren: make manga urls consistent (#1075) manhuaren: make manga urls consistent --- src/zh/manhuaren/build.gradle | 2 +- .../extension/zh/manhuaren/Manhuaren.kt | 153 +++++++++--------- 2 files changed, 80 insertions(+), 75 deletions(-) diff --git a/src/zh/manhuaren/build.gradle b/src/zh/manhuaren/build.gradle index cea9348a8..6808ca986 100644 --- a/src/zh/manhuaren/build.gradle +++ b/src/zh/manhuaren/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: Manhuaren' pkgNameSuffix = 'zh.manhuaren' extClass = '.Manhuaren' - extVersionCode = 4 + extVersionCode = 5 libVersion = '1.2' } diff --git a/src/zh/manhuaren/src/eu/kanade/tachiyomi/extension/zh/manhuaren/Manhuaren.kt b/src/zh/manhuaren/src/eu/kanade/tachiyomi/extension/zh/manhuaren/Manhuaren.kt index 8d0994f32..33901e910 100644 --- a/src/zh/manhuaren/src/eu/kanade/tachiyomi/extension/zh/manhuaren/Manhuaren.kt +++ b/src/zh/manhuaren/src/eu/kanade/tachiyomi/extension/zh/manhuaren/Manhuaren.kt @@ -7,12 +7,15 @@ import eu.kanade.tachiyomi.source.online.HttpSource import okhttp3.Headers import okhttp3.Request import okhttp3.Response +import okhttp3.HttpUrl +import okhttp3.CacheControl import org.json.JSONArray import org.json.JSONObject import java.net.URLEncoder import java.security.MessageDigest import java.text.SimpleDateFormat import java.util.* +import java.util.concurrent.TimeUnit.MINUTES class Manhuaren : HttpSource() { @@ -22,11 +25,39 @@ class Manhuaren : HttpSource() { override val baseUrl = "http://mangaapi.manhuaren.com" private val pageSize = 20 + private val baseHttpUrl = HttpUrl.parse(baseUrl)!! private val c = "4e0a48e1c0b54041bce9c8f0e036124d" + private val cacheControl: CacheControl by lazy { CacheControl.Builder().maxAge(10, MINUTES).build() } - private fun myGet(url: String): Request { - return GET(url, headers) + private fun generateGSNHash(url: HttpUrl): String { + var s = c + "GET" + url.queryParameterNames().toSortedSet().forEach { + if (it != "gsn") { + s += it + s += urlEncode(url.queryParameterValues(it).get(0)) + } + } + s += c + return hashString("MD5", s) + } + + private fun myGet(url: HttpUrl): Request { + val now = DateFormat.format("yyyy-MM-dd+HH:mm:ss", Date()).toString() + val real_url = url.newBuilder() + .setQueryParameter("gsm", "md5") + .setQueryParameter("gft", "json") + .setQueryParameter("gts", now) + .setQueryParameter("gak", "android_manhuaren2") + .setQueryParameter("gat", "") + .setQueryParameter("gaui", "191909801") + .setQueryParameter("gui", "191909801") + .setQueryParameter("gut", "0") + return Request.Builder() + .url(real_url.setQueryParameter("gsn", generateGSNHash(real_url.build())).build()) + .headers(headers) + .cacheControl(cacheControl) + .build() } override fun headersBuilder() = Headers.Builder().apply { @@ -60,33 +91,6 @@ class Manhuaren : HttpSource() { .replace("*", "%2A") } - private fun generateGSNHash(params: MutableMap): String { - var s = c + "GET" - val keys = params.toSortedMap().keys - keys.forEach { - s += it - s += urlEncode(params[it]) - } - s += c - return hashString("MD5", s) - } - - private fun generateApiRequestUrl(path: String, params: MutableMap): String { - val now = DateFormat.format("yyyy-MM-dd+HH:mm:ss", Date()).toString() - - params["gsm"] = "md5" - params["gft"] = "json" - params["gts"] = now - params["gak"] = "android_manhuaren2" - params["gat"] = "" - params["gaui"] = "191909801" - params["gui"] = "191909801" - params["gut"] = "0" - params["gsn"] = generateGSNHash(params) - val queryString = params.map { (key, value) -> "$key=${urlEncode(value)}" }.joinToString("&") - return "$path?$queryString" - } - private fun mangasFromJSONArray(arr: JSONArray): MangasPage { val ret = ArrayList(arr.length()) for (i in 0 until arr.length()) { @@ -101,10 +105,7 @@ class Manhuaren : HttpSource() { 0 -> SManga.ONGOING else -> SManga.UNKNOWN } - url = generateApiRequestUrl( - "/v1/manga/getDetail", - mutableMapOf("mangaId" to id.toString()) - ) + url = "/v1/manga/getDetail?mangaId=$id" }) } return MangasPage(ret, arr.length() != 0) @@ -117,25 +118,27 @@ class Manhuaren : HttpSource() { } override fun popularMangaRequest(page: Int): Request { - val params = mutableMapOf( - "subCategoryType" to "0", - "subCategoryId" to "0", - "start" to (pageSize * (page - 1)).toString(), - "limit" to pageSize.toString(), - "sort" to "0" - ) - return myGet(baseUrl + generateApiRequestUrl("/v2/manga/getCategoryMangas", params)) + val url = baseHttpUrl.newBuilder() + .addQueryParameter("subCategoryType", "0") + .addQueryParameter("subCategoryId", "0") + .addQueryParameter("start", (pageSize * (page - 1)).toString()) + .addQueryParameter("limit", pageSize.toString()) + .addQueryParameter("sort", "0") + .addPathSegments("/v2/manga/getCategoryMangas") + .build() + return myGet(url) } override fun latestUpdatesRequest(page: Int): Request { - val params = mutableMapOf( - "subCategoryType" to "0", - "subCategoryId" to "0", - "start" to (pageSize * (page - 1)).toString(), - "limit" to pageSize.toString(), - "sort" to "1" - ) - return myGet(baseUrl + generateApiRequestUrl("/v2/manga/getCategoryMangas", params)) + val url = baseHttpUrl.newBuilder() + .addQueryParameter("subCategoryType", "0") + .addQueryParameter("subCategoryId", "0") + .addQueryParameter("start", (pageSize * (page - 1)).toString()) + .addQueryParameter("limit", pageSize.toString()) + .addQueryParameter("sort", "1") + .addPathSegments("/v2/manga/getCategoryMangas") + .build() + return myGet(url) } override fun popularMangaParse(response: Response): MangasPage { @@ -147,30 +150,25 @@ class Manhuaren : HttpSource() { } override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + var url = baseHttpUrl.newBuilder() + .addQueryParameter("start", (pageSize * (page - 1)).toString()) + .addQueryParameter("limit", pageSize.toString()) if (query != "") { - return myGet(baseUrl + generateApiRequestUrl( - "/v1/search/getSearchManga", - mutableMapOf( - "keywords" to query, - "start" to (pageSize * (page - 1)).toString(), - "limit" to pageSize.toString() - ) - )) + url = url.addQueryParameter("keywords", query) + .addPathSegments("/v1/search/getSearchManga") + return myGet(url.build()) } - val params = mutableMapOf( - "start" to (pageSize * (page - 1)).toString(), - "limit" to pageSize.toString() - ) filters.forEach { filter -> when (filter) { - is SortFilter -> params["sort"] = filter.getId() + is SortFilter -> url = url.setQueryParameter("sort", filter.getId()) is CategoryFilter -> { - params["subCategoryId"] = filter.getId() - params["subCategoryType"] = filter.getType() + url = url.setQueryParameter("subCategoryId", filter.getId()) + .setQueryParameter("subCategoryType", filter.getType()) } } } - return myGet(baseUrl + generateApiRequestUrl("/v2/manga/getCategoryMangas", params)) + url = url.addPathSegments("/v2/manga/getCategoryMangas") + return myGet(url.build()) } override fun searchMangaParse(response: Response): MangasPage { @@ -219,6 +217,12 @@ class Manhuaren : HttpSource() { description = obj.getString("mangaIntro") } + override fun mangaDetailsRequest(manga: SManga): Request { + return myGet(HttpUrl.parse(baseUrl + manga.url)!!) + } + + override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga) + private fun getChapterName(type: String, name: String, title: String): String { return (if (type == "mangaEpisode") "[番外] " else "") + name + (if (title == "") "" else ": $title") } @@ -232,15 +236,7 @@ class Manhuaren : HttpSource() { name = getChapterName(type, obj.getString("sectionName"), obj.getString("sectionTitle")) date_upload = dateFormat.parse(obj.getString("releaseTime")).time chapter_number = obj.getInt("sectionSort").toFloat() - url = generateApiRequestUrl( - "/v1/manga/getRead", - mutableMapOf( - "mangaSectionId" to obj.getInt("sectionId").toString(), - "netType" to "4", - "loadreal" to "1", - "imageQuality" to "2" - ) - ) + url = "/v1/manga/getRead?mangaSectionId=${obj.getInt("sectionId")}" }) } return ret @@ -271,6 +267,15 @@ class Manhuaren : HttpSource() { return ret } + override fun pageListRequest(chapter: SChapter): Request { + val url = HttpUrl.parse(baseUrl + chapter.url)!!.newBuilder() + .addQueryParameter("netType", "4") + .addQueryParameter("loadreal", "1") + .addQueryParameter("imageQuality", "2") + .build() + return myGet(url) + } + override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("This method should not be called!") override fun getFilterList() = FilterList(