[zh-copymanga]fix chapter list and manga load failed (#8946)
* [zh-copymanga]fix chapter list and manga load failed * remove test code * Set chapter's date_upload to current time, which would make the updated manga displayed in the "Recent updates" section * fix typo * use System.currentTimeMillis() instead * optimize imports * Revert "optimize imports" This reverts commit 6514e517 * revert useless import changes and remove java.util.Date import * fix wrong timestamp * fix an issue that only display the default chapters
This commit is contained in:
parent
8198cab8e2
commit
cf6ed5c5c0
|
@ -5,7 +5,7 @@ ext {
|
||||||
extName = 'CopyManga'
|
extName = 'CopyManga'
|
||||||
pkgNameSuffix = 'zh.copymanga'
|
pkgNameSuffix = 'zh.copymanga'
|
||||||
extClass = '.CopyManga'
|
extClass = '.CopyManga'
|
||||||
extVersionCode = 11
|
extVersionCode = 12
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
|
@ -25,7 +25,6 @@ import uy.kohesive.injekt.api.get
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import javax.crypto.Cipher
|
import javax.crypto.Cipher
|
||||||
import javax.crypto.spec.IvParameterSpec
|
import javax.crypto.spec.IvParameterSpec
|
||||||
|
@ -137,60 +136,60 @@ class CopyManga : ConfigurableSource, HttpSource() {
|
||||||
override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga)
|
override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga)
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val disposableData = document.select("div.disposableData").first().attr("disposable")
|
|
||||||
val disposablePass = document.select("div.disposablePass").first().attr("disposable")
|
val disposablePass = document.select("div.disposablePass").first().attr("disposable")
|
||||||
|
|
||||||
|
// Get encrypted chapters data from another endpoint
|
||||||
|
val chapterResponse = client.newCall(GET("${response.request.url}/chapters", headers)).execute()
|
||||||
|
val disposableData = JSONObject(chapterResponse.body!!.string()).get("results").toString()
|
||||||
|
|
||||||
|
// Decrypt chapter JSON
|
||||||
val chapterJsonString = decryptChapterData(disposableData, disposablePass)
|
val chapterJsonString = decryptChapterData(disposableData, disposablePass)
|
||||||
// default > groups > 全部 []
|
|
||||||
val chapterJson = JSONObject(chapterJsonString)
|
val chapterJson = JSONObject(chapterJsonString)
|
||||||
var chapterArray = chapterJson.optJSONObject("default")?.optJSONObject("groups")?.optJSONArray("全部")
|
// Get the comic path word
|
||||||
if (chapterArray == null) {
|
val comicPathWord = chapterJson.optJSONObject("build")?.optString("path_word")
|
||||||
|
|
||||||
|
// Get chapter groups
|
||||||
|
val chapterGroups = chapterJson.optJSONObject("groups")
|
||||||
|
if (chapterGroups == null) {
|
||||||
return listOf()
|
return listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
val retDefault = ArrayList<SChapter>(chapterArray.length())
|
val retChapter = ArrayList<SChapter>()
|
||||||
for (i in 0 until chapterArray.length()) {
|
// Get chapters according to groups
|
||||||
val chapter = chapterArray.getJSONObject(i)
|
chapterGroups.keys().forEach { groupName ->
|
||||||
retDefault.add(
|
run {
|
||||||
SChapter.create().apply {
|
val chapterGroup = chapterGroups.getJSONObject(groupName)
|
||||||
name = chapter.getString("name")
|
|
||||||
date_upload = stringToUnixTimestamp(chapter.getString("datetime_created")) * 1000
|
|
||||||
url = "/comic/${chapter.getString("comic_path_word")}/chapter/${chapter.getString("uuid")}"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// {others} > groups > 全部 []
|
// group's last update time
|
||||||
val retOthers = ArrayList<SChapter>()
|
val groupLastUpdateTime = chapterGroup.optJSONObject("last_chapter")?.optString("datetime_created")
|
||||||
for (categroy in chapterJson.keys()) {
|
|
||||||
if (categroy != "default") {
|
// chapters in the group to
|
||||||
chapterArray = chapterJson.optJSONObject(categroy)?.optJSONObject("groups")?.optJSONArray("全部")
|
val chapterArray = chapterGroup.optJSONArray("chapters")
|
||||||
if (chapterArray == null) {
|
if (chapterArray != null) {
|
||||||
continue
|
|
||||||
}
|
|
||||||
for (i in 0 until chapterArray.length()) {
|
for (i in 0 until chapterArray.length()) {
|
||||||
val chapter = chapterArray.getJSONObject(i)
|
val chapter = chapterArray.getJSONObject(i)
|
||||||
retOthers.add(
|
retChapter.add(
|
||||||
SChapter.create().apply {
|
SChapter.create().apply {
|
||||||
name = chapter.getString("name")
|
name = chapter.getString("name")
|
||||||
date_upload = stringToUnixTimestamp(chapter.getString("datetime_created")) * 1000
|
date_upload = stringToUnixTimestamp(groupLastUpdateTime)
|
||||||
url = "/comic/${chapter.getString("comic_path_word")}/chapter/${chapter.getString("uuid")}"
|
url = "/comic/$comicPathWord/chapter/${chapter.getString("id")}"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// place others to top, as other group updates not so often
|
// place others to top, as other group updates not so often
|
||||||
retDefault.addAll(0, retOthers)
|
return retChapter.asReversed()
|
||||||
return retDefault.asReversed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
|
override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val disposableData = document.select("div.disposableData").first().attr("disposable")
|
val disposableData = document.select("div.disData").first().attr("contentKey")
|
||||||
val disposablePass = document.select("div.disposablePass").first().attr("disposable")
|
val disposablePass = document.select("div.disPass").first().attr("contentKey")
|
||||||
|
|
||||||
val pageJsonString = decryptChapterData(disposableData, disposablePass)
|
val pageJsonString = decryptChapterData(disposableData, disposablePass)
|
||||||
val pageArray = JSONArray(pageJsonString)
|
val pageArray = JSONArray(pageJsonString)
|
||||||
|
@ -392,12 +391,15 @@ class CopyManga : ConfigurableSource, HttpSource() {
|
||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stringToUnixTimestamp(string: String, pattern: String = "yyyy-MM-dd", locale: Locale = Locale.CHINA): Long {
|
private fun stringToUnixTimestamp(string: String?, pattern: String = "yyyy-MM-dd", locale: Locale = Locale.CHINA): Long {
|
||||||
|
if (string == null) System.currentTimeMillis()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
val time = SimpleDateFormat(pattern, locale).parse(string)?.time
|
val time = SimpleDateFormat(pattern, locale).parse(string)?.time
|
||||||
if (time != null) time / 1000 else Date().time / 1000
|
if (time != null) time else System.currentTimeMillis()
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
Date().time / 1000
|
// Set the time to current in order to display the updated manga in the "Recent updates" section
|
||||||
|
System.currentTimeMillis()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue