manhuaren: make manga urls consistent (#1075)

manhuaren: make manga urls consistent
This commit is contained in:
yshui 2019-05-05 22:14:24 +01:00 committed by Eugene
parent 36abd9b3d0
commit 0e446fb7d0
2 changed files with 80 additions and 75 deletions

View File

@ -5,7 +5,7 @@ ext {
appName = 'Tachiyomi: Manhuaren' appName = 'Tachiyomi: Manhuaren'
pkgNameSuffix = 'zh.manhuaren' pkgNameSuffix = 'zh.manhuaren'
extClass = '.Manhuaren' extClass = '.Manhuaren'
extVersionCode = 4 extVersionCode = 5
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -7,12 +7,15 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import okhttp3.HttpUrl
import okhttp3.CacheControl
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.net.URLEncoder import java.net.URLEncoder
import java.security.MessageDigest import java.security.MessageDigest
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit.MINUTES
class Manhuaren : HttpSource() { class Manhuaren : HttpSource() {
@ -22,11 +25,39 @@ class Manhuaren : HttpSource() {
override val baseUrl = "http://mangaapi.manhuaren.com" override val baseUrl = "http://mangaapi.manhuaren.com"
private val pageSize = 20 private val pageSize = 20
private val baseHttpUrl = HttpUrl.parse(baseUrl)!!
private val c = "4e0a48e1c0b54041bce9c8f0e036124d" private val c = "4e0a48e1c0b54041bce9c8f0e036124d"
private val cacheControl: CacheControl by lazy { CacheControl.Builder().maxAge(10, MINUTES).build() }
private fun myGet(url: String): Request { private fun generateGSNHash(url: HttpUrl): String {
return GET(url, headers) 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 { override fun headersBuilder() = Headers.Builder().apply {
@ -60,33 +91,6 @@ class Manhuaren : HttpSource() {
.replace("*", "%2A") .replace("*", "%2A")
} }
private fun generateGSNHash(params: MutableMap<String, String>): 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, String>): 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 { private fun mangasFromJSONArray(arr: JSONArray): MangasPage {
val ret = ArrayList<SManga>(arr.length()) val ret = ArrayList<SManga>(arr.length())
for (i in 0 until arr.length()) { for (i in 0 until arr.length()) {
@ -101,10 +105,7 @@ class Manhuaren : HttpSource() {
0 -> SManga.ONGOING 0 -> SManga.ONGOING
else -> SManga.UNKNOWN else -> SManga.UNKNOWN
} }
url = generateApiRequestUrl( url = "/v1/manga/getDetail?mangaId=$id"
"/v1/manga/getDetail",
mutableMapOf("mangaId" to id.toString())
)
}) })
} }
return MangasPage(ret, arr.length() != 0) return MangasPage(ret, arr.length() != 0)
@ -117,25 +118,27 @@ class Manhuaren : HttpSource() {
} }
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
val params = mutableMapOf( val url = baseHttpUrl.newBuilder()
"subCategoryType" to "0", .addQueryParameter("subCategoryType", "0")
"subCategoryId" to "0", .addQueryParameter("subCategoryId", "0")
"start" to (pageSize * (page - 1)).toString(), .addQueryParameter("start", (pageSize * (page - 1)).toString())
"limit" to pageSize.toString(), .addQueryParameter("limit", pageSize.toString())
"sort" to "0" .addQueryParameter("sort", "0")
) .addPathSegments("/v2/manga/getCategoryMangas")
return myGet(baseUrl + generateApiRequestUrl("/v2/manga/getCategoryMangas", params)) .build()
return myGet(url)
} }
override fun latestUpdatesRequest(page: Int): Request { override fun latestUpdatesRequest(page: Int): Request {
val params = mutableMapOf( val url = baseHttpUrl.newBuilder()
"subCategoryType" to "0", .addQueryParameter("subCategoryType", "0")
"subCategoryId" to "0", .addQueryParameter("subCategoryId", "0")
"start" to (pageSize * (page - 1)).toString(), .addQueryParameter("start", (pageSize * (page - 1)).toString())
"limit" to pageSize.toString(), .addQueryParameter("limit", pageSize.toString())
"sort" to "1" .addQueryParameter("sort", "1")
) .addPathSegments("/v2/manga/getCategoryMangas")
return myGet(baseUrl + generateApiRequestUrl("/v2/manga/getCategoryMangas", params)) .build()
return myGet(url)
} }
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
@ -147,30 +150,25 @@ class Manhuaren : HttpSource() {
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { 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 != "") { if (query != "") {
return myGet(baseUrl + generateApiRequestUrl( url = url.addQueryParameter("keywords", query)
"/v1/search/getSearchManga", .addPathSegments("/v1/search/getSearchManga")
mutableMapOf( return myGet(url.build())
"keywords" to query,
"start" to (pageSize * (page - 1)).toString(),
"limit" to pageSize.toString()
)
))
} }
val params = mutableMapOf(
"start" to (pageSize * (page - 1)).toString(),
"limit" to pageSize.toString()
)
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
is SortFilter -> params["sort"] = filter.getId() is SortFilter -> url = url.setQueryParameter("sort", filter.getId())
is CategoryFilter -> { is CategoryFilter -> {
params["subCategoryId"] = filter.getId() url = url.setQueryParameter("subCategoryId", filter.getId())
params["subCategoryType"] = filter.getType() .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 { override fun searchMangaParse(response: Response): MangasPage {
@ -219,6 +217,12 @@ class Manhuaren : HttpSource() {
description = obj.getString("mangaIntro") 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 { private fun getChapterName(type: String, name: String, title: String): String {
return (if (type == "mangaEpisode") "[番外] " else "") + name + (if (title == "") "" else ": $title") 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")) name = getChapterName(type, obj.getString("sectionName"), obj.getString("sectionTitle"))
date_upload = dateFormat.parse(obj.getString("releaseTime")).time date_upload = dateFormat.parse(obj.getString("releaseTime")).time
chapter_number = obj.getInt("sectionSort").toFloat() chapter_number = obj.getInt("sectionSort").toFloat()
url = generateApiRequestUrl( url = "/v1/manga/getRead?mangaSectionId=${obj.getInt("sectionId")}"
"/v1/manga/getRead",
mutableMapOf(
"mangaSectionId" to obj.getInt("sectionId").toString(),
"netType" to "4",
"loadreal" to "1",
"imageQuality" to "2"
)
)
}) })
} }
return ret return ret
@ -271,6 +267,15 @@ class Manhuaren : HttpSource() {
return ret 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 imageUrlParse(response: Response) = throw UnsupportedOperationException("This method should not be called!")
override fun getFilterList() = FilterList( override fun getFilterList() = FilterList(