diff --git a/app/build.gradle b/app/build.gradle index 0fd9f2a61..38514e8a5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdkVersion 21 targetSdkVersion 31 - versionCode 376 - versionName '2.1' + versionCode 377 + versionName '2.1.1' generatedDensities = [] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt index afae79bab..0b5fd9b65 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt @@ -93,14 +93,14 @@ class DesuMeRepository(loaderContext: MangaLoaderContext) : RemoteMangaRepositor description = json.getString("description"), chapters = chaptersList.mapIndexed { i, it -> val chid = it.getLong("id") - val volChap = "Том " + it.getString("vol") + ". " + "Глава " + it.getString("ch") - val title = if (it.getString("title") == "null") "" else it.getString("title") + val volChap = "Том " + it.optString("vol", "0") + ". " + "Глава " + it.optString("ch", "0") + val title = it.optString("title", "null").takeUnless { it == "null" } MangaChapter( id = generateUid(chid), source = manga.source, url = "$baseChapterUrl$chid", uploadDate = it.getLong("date") * 1000, - name = if (title.isEmpty()) volChap else "$volChap: $title", + name = if (title.isNullOrEmpty()) volChap else "$volChap: $title", number = totalChapters - i, scanlator = null, branch = null, diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaDexRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaDexRepository.kt index efce0b7a7..2d22a7fd4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaDexRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaDexRepository.kt @@ -148,7 +148,7 @@ class MangaDexRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit chapters = feed.mapNotNull { jo -> val id = jo.getString("id") val attrs = jo.getJSONObject("attributes") - if (attrs.optJSONArray("data").isNullOrEmpty()) { + if (!attrs.isNull("externalUrl")) { return@mapNotNull null } val locale = Locale.forLanguageTag(attrs.getString("translatedLanguage")) @@ -175,11 +175,11 @@ class MangaDexRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit .parseJson() .getJSONObject("data") .getJSONObject("attributes") - val data = attrs.getJSONArray("data") + val pages = attrs.getJSONArray("pages") val prefix = "https://uploads.$domain/data/${attrs.getString("hash")}/" val referer = "https://$domain/" - return List(data.length()) { i -> - val url = prefix + data.getString(i) + return List(pages.length()) { i -> + val url = prefix + pages.getString(i) MangaPage( id = generateUid(url), url = url, diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangareadRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangareadRepository.kt index 17aced99d..7999fb7f2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangareadRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangareadRepository.kt @@ -55,7 +55,7 @@ class MangareadRepository( id = generateUid(href), url = href, publicUrl = href.inContextOf(div), - coverUrl = div.selectFirst("img")?.absUrl("src").orEmpty(), + coverUrl = div.selectFirst("img")?.absUrl("data-src").orEmpty(), title = summary?.selectFirst("h3")?.text().orEmpty(), rating = div.selectFirst("span.total_votes")?.ownText() ?.toFloatOrNull()?.div(5f) ?: -1f, @@ -107,16 +107,6 @@ class MangareadRepository( val root2 = doc.body().selectFirst("div.content-area") ?.selectFirst("div.c-page") ?: throw ParseException("Root2 not found") - val mangaId = doc.getElementsByAttribute("data-post").firstOrNull() - ?.attr("data-post")?.toLongOrNull() - ?: throw ParseException("Cannot obtain manga id") - val doc2 = loaderContext.httpPost( - "https://${getDomain()}/wp-admin/admin-ajax.php", - mapOf( - "action" to "manga_get_chapters", - "manga" to mangaId.toString() - ) - ).parseHtml() val dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US) return manga.copy( tags = root.selectFirst("div.genres-content")?.select("a") @@ -132,7 +122,7 @@ class MangareadRepository( ?.select("p") ?.filterNot { it.ownText().startsWith("A brief description") } ?.joinToString { it.html() }, - chapters = doc2.select("li").asReversed().mapIndexed { i, li -> + chapters = root2.select("li").asReversed().mapIndexed { i, li -> val a = li.selectFirst("a") val href = a?.relUrl("href").orEmpty().ifEmpty { parseFailed("Link is missing") @@ -144,7 +134,7 @@ class MangareadRepository( url = href, uploadDate = parseChapterDate( dateFormat, - doc2.selectFirst("span.chapter-release-date i")?.text() + li.selectFirst("span.chapter-release-date i")?.text() ), source = MangaSource.MANGAREAD, scanlator = null, 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 d589a9490..2319dfcd2 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 @@ -125,10 +125,10 @@ class RemangaRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposito number = chapters.length() - i, name = buildString { append("Том ") - append(jo.getString("tome")) + append(jo.optString("tome", "0")) append(". ") append("Глава ") - append(jo.getString("chapter")) + append(jo.optString("chapter", "0")) if (name.isNotEmpty()) { append(" - ") append(name) diff --git a/app/src/test/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepositoryTest.kt b/app/src/test/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepositoryTest.kt index e498e919f..bdfa3f735 100644 --- a/app/src/test/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepositoryTest.kt +++ b/app/src/test/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepositoryTest.kt @@ -6,6 +6,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.koin.core.component.inject +import org.koin.core.logger.Level import org.koin.core.parameter.parametersOf import org.koin.test.KoinTest import org.koin.test.KoinTestRule @@ -18,7 +19,7 @@ import org.koitharu.kotatsu.utils.TestResponse import org.koitharu.kotatsu.utils.ext.mapToSet import org.koitharu.kotatsu.utils.ext.medianOrNull import org.koitharu.kotatsu.utils.isAbsoluteUrl -import org.koitharu.kotatsu.utils.isRelativeUrl +import org.koitharu.kotatsu.utils.isNotAbsoluteUrl @RunWith(Parameterized::class) class RemoteMangaRepositoryTest(private val source: MangaSource) : KoinTest { @@ -29,7 +30,7 @@ class RemoteMangaRepositoryTest(private val source: MangaSource) : KoinTest { @get:Rule val koinTestRule = KoinTestRule.create { - printLogger() + printLogger(Level.ERROR) modules(repositoryTestModule) } @@ -112,7 +113,7 @@ class RemoteMangaRepositoryTest(private val source: MangaSource) : KoinTest { Truth.assertThat(list.map { it.id }).containsNoDuplicates() for (item in list) { Truth.assertThat(item.url).isNotEmpty() - Truth.assertThat(item.url).isRelativeUrl() + Truth.assertThat(item.url).isNotAbsoluteUrl() Truth.assertThat(item.coverUrl).isAbsoluteUrl() Truth.assertThat(item.title).isNotEmpty() Truth.assertThat(item.publicUrl).isAbsoluteUrl() diff --git a/app/src/test/java/org/koitharu/kotatsu/utils/CoroutineTestRule.kt b/app/src/test/java/org/koitharu/kotatsu/utils/CoroutineTestRule.kt index 4558ef197..1f9354a72 100644 --- a/app/src/test/java/org/koitharu/kotatsu/utils/CoroutineTestRule.kt +++ b/app/src/test/java/org/koitharu/kotatsu/utils/CoroutineTestRule.kt @@ -3,25 +3,25 @@ package org.koitharu.kotatsu.utils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.TestCoroutineDispatcher +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestDispatcher import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.setMain import org.junit.rules.TestWatcher import org.junit.runner.Description class CoroutineTestRule( - private val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher(), + private val testDispatcher: TestDispatcher = StandardTestDispatcher(), ) : TestWatcher() { - override fun starting(description: Description?) { + override fun starting(description: Description) { super.starting(description) Dispatchers.setMain(testDispatcher) } - override fun finished(description: Description?) { + override fun finished(description: Description) { super.finished(description) Dispatchers.resetMain() - testDispatcher.cleanupTestCoroutines() } fun runBlockingTest(block: suspend CoroutineScope.() -> Unit) { diff --git a/app/src/test/java/org/koitharu/kotatsu/utils/TruthExt.kt b/app/src/test/java/org/koitharu/kotatsu/utils/TruthExt.kt index 14f62bfc2..8e99bb1a9 100644 --- a/app/src/test/java/org/koitharu/kotatsu/utils/TruthExt.kt +++ b/app/src/test/java/org/koitharu/kotatsu/utils/TruthExt.kt @@ -8,4 +8,6 @@ private val PATTERN_URL_RELATIVE = Pattern.compile("^/[^\\s]+", Pattern.CASE_INS fun StringSubject.isRelativeUrl() = matches(PATTERN_URL_RELATIVE) -fun StringSubject.isAbsoluteUrl() = matches(PATTERN_URL_ABSOLUTE) \ No newline at end of file +fun StringSubject.isAbsoluteUrl() = matches(PATTERN_URL_ABSOLUTE) + +fun StringSubject.isNotAbsoluteUrl() = doesNotMatch(PATTERN_URL_ABSOLUTE) \ No newline at end of file