diff --git a/app/build.gradle b/app/build.gradle index 25140cfc3..30f04235b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdkVersion 21 targetSdkVersion 31 - versionCode 380 - versionName '2.1.4' + versionCode 381 + versionName '2.1.5' generatedDensities = [] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/RemangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/RemangaRepository.kt index 2319dfcd2..ebea9bc94 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/RemangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/RemangaRepository.kt @@ -9,6 +9,7 @@ import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.MangaRepositoryAuthProvider import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.utils.ext.* +import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* @@ -32,7 +33,7 @@ class RemangaRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposito offset: Int, query: String?, tags: Set?, - sortOrder: SortOrder? + sortOrder: SortOrder?, ): List { copyCookies() val domain = getDomain() @@ -97,9 +98,7 @@ class RemangaRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposito } val branchId = content.getJSONArray("branches").optJSONObject(0) ?.getLong("id") ?: throw ParseException("No branches found") - val chapters = loaderContext.httpGet( - url = "https://api.$domain/api/titles/chapters/?branch_id=$branchId" - ).parseJson().getJSONArray("content") + val chapters = grabChapters(domain, branchId) val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US) return manga.copy( description = content.getString("description"), @@ -118,11 +117,11 @@ class RemangaRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposito chapters = chapters.mapIndexed { i, jo -> val id = jo.getLong("id") val name = jo.getString("name").toTitleCase(Locale.ROOT) - val publishers = jo.getJSONArray("publishers") + val publishers = jo.optJSONArray("publishers") MangaChapter( id = generateUid(id), url = "/api/titles/chapters/$id/", - number = chapters.length() - i, + number = chapters.size - i, name = buildString { append("Том ") append(jo.optString("tome", "0")) @@ -135,7 +134,7 @@ class RemangaRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposito } }, uploadDate = dateFormat.tryParse(jo.getString("upload_date")), - scanlator = publishers.optJSONObject(0)?.getStringOrNull("name"), + scanlator = publishers?.optJSONObject(0)?.getStringOrNull("name"), source = MangaSource.REMANGA, branch = null, ) @@ -146,16 +145,28 @@ class RemangaRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposito override suspend fun getPages(chapter: MangaChapter): List { val referer = "https://${getDomain()}/" val content = loaderContext.httpGet(chapter.url.withDomain(subdomain = "api")).parseJson() - .getJSONObject("content").getJSONArray("pages") - val pages = ArrayList(content.length()) - for (i in 0 until content.length()) { - when (val item = content.get(i)) { - is JSONObject -> pages += parsePage(item, referer) - is JSONArray -> item.mapTo(pages) { parsePage(it, referer) } + .getJSONObject("content") + val pages = content.optJSONArray("pages") + if (pages == null) { + val pubDate = content.getStringOrNull("pub_date")?.let { + SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).tryParse(it) + } + if (pubDate != null && pubDate > System.currentTimeMillis()) { + val at = SimpleDateFormat.getDateInstance(DateFormat.LONG).format(Date(pubDate)) + parseFailed("Глава станет доступной $at") + } else { + parseFailed("Глава недоступна") + } + } + val result = ArrayList(pages.length()) + for (i in 0 until pages.length()) { + when (val item = pages.get(i)) { + is JSONObject -> result += parsePage(item, referer) + is JSONArray -> item.mapTo(result) { parsePage(it, referer) } else -> throw ParseException("Unknown json item $item") } } - return pages + return result } override suspend fun getTags(): Set { @@ -198,6 +209,26 @@ class RemangaRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposito source = source, ) + private suspend fun grabChapters(domain: String, branchId: Long): List { + val result = ArrayList(100) + var page = 1 + while (true) { + val content = loaderContext.httpGet( + "https://api.$domain/api/titles/chapters/?branch_id=$branchId&page=$page&count=100" + ).parseJson().getJSONArray("content") + val len = content.length() + if (len == 0) { + break + } + result.ensureCapacity(result.size + len) + for (i in 0 until len) { + result.add(content.getJSONObject(i)) + } + page++ + } + return result + } + private companion object { const val PAGE_SIZE = 30 diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml index c6116aaa4..7dac5f16b 100644 --- a/app/src/main/res/xml/filepaths.xml +++ b/app/src/main/res/xml/filepaths.xml @@ -3,6 +3,9 @@ +