From 53ff72f22c2ae81ff6878ddd9dd04d6014b524cd Mon Sep 17 00:00:00 2001 From: Chopper <156493704+choppeh@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:09:54 -0300 Subject: [PATCH] AnimeXNovel: Fix loading chapters (#9392) Fix loading chapters --- src/pt/animexnovel/build.gradle | 2 +- .../extension/pt/animexnovel/AnimeXNovel.kt | 86 +++++++++++++------ .../pt/animexnovel/AnimeXNovelDto.kt | 15 ++++ 3 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 src/pt/animexnovel/src/eu/kanade/tachiyomi/extension/pt/animexnovel/AnimeXNovelDto.kt diff --git a/src/pt/animexnovel/build.gradle b/src/pt/animexnovel/build.gradle index 16597c3c7..ff75a9733 100644 --- a/src/pt/animexnovel/build.gradle +++ b/src/pt/animexnovel/build.gradle @@ -3,7 +3,7 @@ ext { extClass = '.AnimeXNovel' themePkg = 'zeistmanga' baseUrl = 'https://www.animexnovel.com' - overrideVersionCode = 1 + overrideVersionCode = 2 isNsfw = false } diff --git a/src/pt/animexnovel/src/eu/kanade/tachiyomi/extension/pt/animexnovel/AnimeXNovel.kt b/src/pt/animexnovel/src/eu/kanade/tachiyomi/extension/pt/animexnovel/AnimeXNovel.kt index d83234cb7..82f2cadea 100644 --- a/src/pt/animexnovel/src/eu/kanade/tachiyomi/extension/pt/animexnovel/AnimeXNovel.kt +++ b/src/pt/animexnovel/src/eu/kanade/tachiyomi/extension/pt/animexnovel/AnimeXNovel.kt @@ -1,15 +1,19 @@ package eu.kanade.tachiyomi.extension.pt.animexnovel import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga -import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistMangaDto import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.util.asJsoup -import kotlinx.serialization.decodeFromString +import keiyoushi.utils.parseAs +import keiyoushi.utils.tryParse import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Response +import org.jsoup.nodes.Element +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.Locale class AnimeXNovel : ZeistManga( "AnimeXNovel", @@ -24,19 +28,13 @@ class AnimeXNovel : ZeistManga( override val popularMangaSelectorUrl = popularMangaSelectorTitle override fun popularMangaParse(response: Response): MangasPage { - return super.popularMangaParse(response).let { mangaPage -> - mangaPage.mangas.filter { it.title.contains("[Mangá]") }.let { - mangaPage.copy(it) - } - } + return super.popularMangaParse(response).let(::filterMangaEntries) } // ============================== Latest =============================== override fun latestUpdatesParse(response: Response): MangasPage { - return super.latestUpdatesParse(response).let { - it.copy(it.mangas.filter { it.title.contains("[Mangá]") }) - } + return super.latestUpdatesParse(response).let(::filterMangaEntries) } // ============================== Details =============================== @@ -47,7 +45,7 @@ class AnimeXNovel : ZeistManga( thumbnail_url = document.selectFirst(".thumb")?.absUrl("src") description = document.selectFirst("#synopsis")?.text() document.selectFirst("span[data-status]")?.let { - status = parseStatus(it.text()) + status = parseStatus(it.text().lowercase()) } genre = document.select("dl:has(dt:contains(Gênero)) dd a") .joinToString { it.text() } @@ -57,31 +55,67 @@ class AnimeXNovel : ZeistManga( // ============================== Chapters =============================== - override val chapterCategory = "Capítulo" - override fun chapterListParse(response: Response): List { val document = response.asJsoup() - val url = getChapterFeedUrl(document).toHttpUrl().newBuilder() - .setQueryParameter("start-index", "1") + val label = document.select("script") + .map(Element::data) + .firstOrNull(MANGA_TITLE_REGEX::containsMatchIn)?.let { + MANGA_TITLE_REGEX.find(it)?.groups?.get(1)?.value + } ?: return emptyList() - val chapters = mutableListOf() - do { - val res = client.newCall(GET(url.build(), headers)).execute() + val script = document.select("script") + .map(Element::data) + .firstOrNull(API_KEY_REGEX::containsMatchIn) + ?: return emptyList() - val page = json.decodeFromString(res.body.string()).feed?.entry - ?.filter { it.category.orEmpty().any { category -> category.term == chapterCategory } } - ?.map { it.toSChapter(baseUrl) } - ?: emptyList() + val blogId = BLOG_ID_REGEX.find(script)?.groups?.get(1)?.value ?: return emptyList() + val apiKey = API_KEY_REGEX.find(script)?.groups?.get(1)?.value ?: return emptyList() - chapters += page - url.setQueryParameter("start-index", "${chapters.size + 1}") - } while (page.isNotEmpty()) + val url = "https://www.googleapis.com/blogger/v3/blogs/$blogId/posts".toHttpUrl().newBuilder() + .addQueryParameter("key", apiKey) + .addQueryParameter("labels", label) + .addQueryParameter("maxResults", "500") + .build() - return chapters + val response = client.newCall(GET(url, headers)).execute() + + if (response.isSuccessful.not()) { + throw IOException("Capítulos não encontrados") + } + + return response.parseAs().items.map { + SChapter.create().apply { + name = it.title + date_upload = dateFormat.tryParse(it.published) + setUrlWithoutDomain(it.url) + } + } } // ============================== Pages =============================== override val pageListSelector = "#reader .separator" + + // ============================== Utils =============================== + + private fun filterMangaEntries(mangasPage: MangasPage): MangasPage { + val prefix = "[Mangá]" + return mangasPage.copy( + mangasPage.mangas.filter { + it.title.contains(prefix) + }.map { + it.apply { + title = title.substringAfter(prefix).trim() + } + }, + ) + } + + companion object { + private val API_KEY_REGEX = """(?:API_KEY(?:\s+)?=(?:\s+)?.)"([^(\\|")]+)""".toRegex() + private val BLOG_ID_REGEX = """(?:BLOG_ID(?:\s+)?=(?:\s+)?.)"([^(\\|")]+)""".toRegex() + private val MANGA_TITLE_REGEX = """iniciarCapituloLoader\("([^"]+)"\)""".toRegex() + private val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ROOT) + } } diff --git a/src/pt/animexnovel/src/eu/kanade/tachiyomi/extension/pt/animexnovel/AnimeXNovelDto.kt b/src/pt/animexnovel/src/eu/kanade/tachiyomi/extension/pt/animexnovel/AnimeXNovelDto.kt new file mode 100644 index 000000000..c0119129b --- /dev/null +++ b/src/pt/animexnovel/src/eu/kanade/tachiyomi/extension/pt/animexnovel/AnimeXNovelDto.kt @@ -0,0 +1,15 @@ +package eu.kanade.tachiyomi.extension.pt.animexnovel + +import kotlinx.serialization.Serializable + +@Serializable +class ChapterWrapperDto( + val items: List, +) + +@Serializable +class ChapterDto( + val title: String, + val published: String, + val url: String, +)