From b047049968335a41f931c291ee02f79849a4ddd0 Mon Sep 17 00:00:00 2001 From: imper1aldev <23511335+imper1aldev@users.noreply.github.com> Date: Sun, 8 Dec 2024 23:35:15 -0600 Subject: [PATCH] MetroSeries fixes Closes #370 --- src/es/metroseries/build.gradle | 2 +- .../es/metroseries/MetroSeries.kt | 212 +++++++----------- 2 files changed, 80 insertions(+), 134 deletions(-) diff --git a/src/es/metroseries/build.gradle b/src/es/metroseries/build.gradle index 663d2c8f..c1bbfb8f 100644 --- a/src/es/metroseries/build.gradle +++ b/src/es/metroseries/build.gradle @@ -1,7 +1,7 @@ ext { extName = 'MetroSeries' extClass = '.MetroSeries' - extVersionCode = 11 + extVersionCode = 12 } apply from: "$rootDir/common.gradle" diff --git a/src/es/metroseries/src/eu/kanade/tachiyomi/animeextension/es/metroseries/MetroSeries.kt b/src/es/metroseries/src/eu/kanade/tachiyomi/animeextension/es/metroseries/MetroSeries.kt index fe841e3c..44a3d78a 100644 --- a/src/es/metroseries/src/eu/kanade/tachiyomi/animeextension/es/metroseries/MetroSeries.kt +++ b/src/es/metroseries/src/eu/kanade/tachiyomi/animeextension/es/metroseries/MetroSeries.kt @@ -20,25 +20,20 @@ import eu.kanade.tachiyomi.lib.upstreamextractor.UpstreamExtractor import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking -import eu.kanade.tachiyomi.util.parallelMapBlocking import okhttp3.FormBody -import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Request import okhttp3.Response import org.jsoup.nodes.Element import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -import java.text.SimpleDateFormat -import java.util.Locale class MetroSeries : ConfigurableAnimeSource, AnimeHttpSource() { override val name = "MetroSeries" - override val baseUrl = "https://metroseries.net" + override val baseUrl = "https://www3.seriesmetro.net" override val lang = "es" @@ -71,11 +66,11 @@ class MetroSeries : ConfigurableAnimeSource, AnimeHttpSource() { ) } - override fun popularAnimeRequest(page: Int) = GET("$baseUrl/series/page/$page", headers) + override fun popularAnimeRequest(page: Int) = GET("$baseUrl/cartelera-series/page/$page", headers) override fun popularAnimeParse(response: Response): AnimesPage { val document = response.asJsoup() - val elements = document.select(".post-list, .results-post > .post") + val elements = document.select(".post") val nextPage = document.select(".nav-links .current ~ a").any() val animeList = elements.map { element -> SAnime.create().apply { @@ -99,11 +94,11 @@ class MetroSeries : ConfigurableAnimeSource, AnimeHttpSource() { override fun animeDetailsParse(response: Response): SAnime { val document = response.asJsoup() return SAnime.create().apply { - title = document.selectFirst("main .entry-header .entry-title")?.text() ?: "" - description = document.select("main .entry-content p").joinToString { it.text() } - thumbnail_url = document.selectFirst("main .post-thumbnail img")?.let { getImageUrl(it) } - genre = document.select("main .entry-content .tagcloud a").joinToString { it.text() } - status = SAnime.UNKNOWN + title = document.selectFirst("aside .entry-header .entry-title")?.text() ?: "" + description = document.select("aside .description p:not([class])").joinToString { it.text() } + thumbnail_url = document.selectFirst(".post-thumbnail img")?.let { getImageUrl(it)?.replace("/w185/", "/w500/") } + genre = document.select(".genres a").joinToString { it.text() } + status = if (document.location().contains("pelicula")) SAnime.COMPLETED else SAnime.UNKNOWN } } @@ -118,34 +113,40 @@ class MetroSeries : ConfigurableAnimeSource, AnimeHttpSource() { override fun episodeListParse(response: Response): List { val document = response.asJsoup() val referer = response.request.url.toString() - val chunkSize = Runtime.getRuntime().availableProcessors() - val objectNumber = document.select("#aa-season").attr("data-object") - val episodes = document.select(".season-list li a") - .sortedByDescending { it.attr("data-season") } - .chunked(chunkSize).flatMap { chunk -> - chunk.parallelCatchingFlatMapBlocking { season -> - val pages = getDetailSeason(season, objectNumber, referer) - getPageEpisodeList(pages, referer, objectNumber, season.attr("data-season")) + return if (referer.contains("pelicula")) { + listOf( + SEpisode.create().apply { + episode_number = 1f + name = "Película" + setUrlWithoutDomain(referer) + }, + ) + } else { + val chunkSize = Runtime.getRuntime().availableProcessors() + document.select(".sel-temp a") + .sortedByDescending { it.attr("data-season") } + .chunked(chunkSize).flatMap { chunk -> + chunk.parallelCatchingFlatMapBlocking { season -> + getDetailSeason(season, referer) + } + }.sortedByDescending { + it.name.substringBeforeLast("-") } - }.sortedByDescending { - it.name.substringBeforeLast("-") - } - return episodes + } } - private fun getDetailSeason(element: Element, objectNumber: String, referer: String): IntRange { - try { + private fun getDetailSeason(element: Element, referer: String): List { + return try { val post = element.attr("data-post") val season = element.attr("data-season") val formBody = FormBody.Builder() .add("action", "action_select_season") .add("season", season) .add("post", post) - .add("object", objectNumber) .build() val request = Request.Builder() - .url("https://metroseries.net/wp-admin/admin-ajax.php") + .url("$baseUrl/wp-admin/admin-ajax.php") .post(formBody) .header("Origin", baseUrl) .header("Referer", referer) @@ -153,110 +154,72 @@ class MetroSeries : ConfigurableAnimeSource, AnimeHttpSource() { .build() val detail = client.newCall(request).execute().asJsoup() - val firstPage = try { detail.selectFirst("#aa-season > nav > span.page-numbers")?.text()?.toInt() ?: 1 } catch (_: Exception) { 1 } - val lastPage = try { detail.select(".pagination a.page-numbers:not(.next)").last()?.text()?.toInt() ?: firstPage } catch (_: Exception) { firstPage } + detail.select(".post").reversed().mapIndexed { idx, it -> + val epNumber = try { + it.select(".entry-header .num-epi").text().substringAfter("x").substringBefore("–").trim() + } catch (_: Exception) { "${idx + 1}" } - return firstPage.rangeTo(lastPage) - } catch (_: Exception) { - return 1..1 - } - } - - private fun getPageEpisodeList(pages: IntRange, referer: String, objectNumber: String, season: String): List { - val episodes = mutableListOf() - try { - pages.parallelMapBlocking { - val formBody = FormBody.Builder() - .add("action", "action_pagination_ep") - .add("page", "$it") - .add("object", objectNumber) - .add("season", season) - .build() - - val requestPage = Request.Builder() - .url("https://metroseries.net/wp-admin/admin-ajax.php") - .post(formBody) - .header("authority", baseUrl.toHttpUrl().host) - .header("Origin", "https://${baseUrl.toHttpUrl().host}") - .header("Referer", referer) - .header("Content-Type", "application/x-www-form-urlencoded") - .build() - - client.newCall(requestPage).await().parseAsEpisodeList().also(episodes::addAll) + SEpisode.create().apply { + setUrlWithoutDomain(it.select("a").attr("abs:href")) + name = "T$season - Episodio $epNumber" + episode_number = epNumber.toFloat() + } } - } catch (_: Exception) { } - return episodes + } catch (_: Exception) { + emptyList() + } } override fun videoListParse(response: Response): List