From 8b19765288d96c7d7fe1807289868a23ddb3afaf Mon Sep 17 00:00:00 2001 From: bapeey <90949336+bapeey@users.noreply.github.com> Date: Sun, 4 Feb 2024 09:47:57 -0500 Subject: [PATCH] Add MangaEsp (#970) * Add MangaEsp * Remove log * Move filtering * Suggested changes * Change messages --------- Co-authored-by: Axel Vargas --- src/es/mangaesp/build.gradle | 8 + .../mangaesp/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3432 bytes .../mangaesp/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2065 bytes .../mangaesp/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4379 bytes .../res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7492 bytes .../res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9981 bytes .../extension/es/mangaesp/MangaEsp.kt | 261 ++++++++++++++++++ .../extension/es/mangaesp/MangaEspDto.kt | 91 ++++++ 8 files changed, 360 insertions(+) create mode 100644 src/es/mangaesp/build.gradle create mode 100644 src/es/mangaesp/res/mipmap-hdpi/ic_launcher.png create mode 100644 src/es/mangaesp/res/mipmap-mdpi/ic_launcher.png create mode 100644 src/es/mangaesp/res/mipmap-xhdpi/ic_launcher.png create mode 100644 src/es/mangaesp/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 src/es/mangaesp/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 src/es/mangaesp/src/eu/kanade/tachiyomi/extension/es/mangaesp/MangaEsp.kt create mode 100644 src/es/mangaesp/src/eu/kanade/tachiyomi/extension/es/mangaesp/MangaEspDto.kt diff --git a/src/es/mangaesp/build.gradle b/src/es/mangaesp/build.gradle new file mode 100644 index 000000000..5c587dc3e --- /dev/null +++ b/src/es/mangaesp/build.gradle @@ -0,0 +1,8 @@ +ext { + extName = 'MangaEsp' + extClass = '.MangaEsp' + extVersionCode = 1 + isNsfw = false +} + +apply from: "$rootDir/common.gradle" diff --git a/src/es/mangaesp/res/mipmap-hdpi/ic_launcher.png b/src/es/mangaesp/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..04cbad788efe075fc7dd0f7718d063b2a23613aa GIT binary patch literal 3432 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 KMNUMnLSTXww3Gz^ literal 0 HcmV?d00001 diff --git a/src/es/mangaesp/res/mipmap-mdpi/ic_launcher.png b/src/es/mangaesp/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..c30ca36c57fea0c8cb7b08965203abad157d552c GIT binary patch literal 2065 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 literal 0 HcmV?d00001 diff --git a/src/es/mangaesp/res/mipmap-xhdpi/ic_launcher.png b/src/es/mangaesp/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4232beaa7a23e5af27146414fc5ce1bd3e77bf5b GIT binary patch literal 4379 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 Vzcb{k0WSam002ovPDHLkV1jn_ICKC2 literal 0 HcmV?d00001 diff --git a/src/es/mangaesp/res/mipmap-xxhdpi/ic_launcher.png b/src/es/mangaesp/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..f712909c59ac272ba6ab109f85664e0ea8491fe4 GIT binary patch literal 7492 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 QhJ^xJYI@LW6}#8}2S!-|x&QzG literal 0 HcmV?d00001 diff --git a/src/es/mangaesp/src/eu/kanade/tachiyomi/extension/es/mangaesp/MangaEsp.kt b/src/es/mangaesp/src/eu/kanade/tachiyomi/extension/es/mangaesp/MangaEsp.kt new file mode 100644 index 000000000..15a980ef5 --- /dev/null +++ b/src/es/mangaesp/src/eu/kanade/tachiyomi/extension/es/mangaesp/MangaEsp.kt @@ -0,0 +1,261 @@ +package eu.kanade.tachiyomi.extension.es.mangaesp + +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.asObservableSuccess +import eu.kanade.tachiyomi.network.interceptor.rateLimitHost +import eu.kanade.tachiyomi.source.model.Filter +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.online.HttpSource +import eu.kanade.tachiyomi.util.asJsoup +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import okhttp3.Headers +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response +import org.jsoup.nodes.Element +import rx.Observable +import uy.kohesive.injekt.injectLazy +import java.text.SimpleDateFormat +import java.util.Locale +import kotlin.math.min + +class MangaEsp : HttpSource() { + + override val name = "MangaEsp" + + override val baseUrl = "https://mangaesp.co" + + private val apiBaseUrl = "https://apis.mangaesp.co" + + override val lang = "es" + + override val supportsLatest = true + + private val json: Json by injectLazy() + + private val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US) + + override val client: OkHttpClient = network.client.newBuilder() + .rateLimitHost(baseUrl.toHttpUrl(), 2) + .build() + + override fun headersBuilder(): Headers.Builder = Headers.Builder() + .add("Referer", "$baseUrl/") + + override fun popularMangaRequest(page: Int): Request = GET("$apiBaseUrl/api/topSerie", headers) + + override fun popularMangaParse(response: Response): MangasPage { + val responseData = json.decodeFromString(response.body.string()) + + val topDaily = responseData.response.topDaily.flatten().map { it.data } + val topWeekly = responseData.response.topWeekly.flatten().map { it.data } + val topMonthly = responseData.response.topMonthly.flatten().map { it.data } + + val mangas = (topDaily + topWeekly + topMonthly).distinctBy { it.slug }.map { series -> + SManga.create().apply { + title = series.name + thumbnail_url = series.thumbnail + url = "/ver/${series.slug}" + } + } + + return MangasPage(mangas, false) + } + + override fun latestUpdatesRequest(page: Int): Request = GET("$apiBaseUrl/api/lastUpdates", headers) + + override fun latestUpdatesParse(response: Response): MangasPage { + val responseData = json.decodeFromString(response.body.string()) + + val mangas = responseData.response.map { series -> + SManga.create().apply { + title = series.name + thumbnail_url = series.thumbnail + url = "/ver/${series.slug}" + } + } + + return MangasPage(mangas, false) + } + + private var comicsList = mutableListOf() + + override fun fetchSearchManga( + page: Int, + query: String, + filters: FilterList, + ): Observable { + return if (comicsList.isEmpty()) { + client.newCall(searchMangaRequest(page, query, filters)) + .asObservableSuccess() + .map { searchMangaParse(it, page, query, filters) } + } else { + Observable.just(parseComicsList(page, query, filters)) + } + } + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/api/comics", headers) + + override fun searchMangaParse(response: Response): MangasPage = throw UnsupportedOperationException() + + private fun searchMangaParse(response: Response, page: Int, query: String, filters: FilterList): MangasPage { + val responseData = json.decodeFromString(response.body.string()) + comicsList = responseData.response.toMutableList() + return parseComicsList(page, query, filters) + } + + private var filteredList = mutableListOf() + + private fun parseComicsList(page: Int, query: String, filterList: FilterList): MangasPage { + if (page == 1) { + filteredList.clear() + + if (query.isNotBlank()) { + if (query.length < 2) throw Exception("La búsqueda debe tener al menos 2 caracteres") + filteredList.addAll(comicsList.filter { it.name.contains(query, ignoreCase = true) }) + } else { + filteredList.addAll(comicsList) + } + + val statusFilter = filterList.firstInstanceOrNull() + + if (statusFilter != null) { + filteredList = filteredList.filter { it.status == statusFilter.toUriPart() }.toMutableList() + } + + val sortByFilter = filterList.firstInstanceOrNull() + + if (sortByFilter != null) { + if (sortByFilter.state?.ascending == true) { + when (sortByFilter.selected) { + "name" -> filteredList.sortBy { it.name } + "views" -> filteredList.sortBy { it.trending?.views } + "updated_at" -> filteredList.sortBy { it.lastChapterDate } + "created_at" -> filteredList.sortBy { it.createdAt } + } + } else { + when (sortByFilter.selected) { + "name" -> filteredList.sortByDescending { it.name } + "views" -> filteredList.sortByDescending { it.trending?.views } + "updated_at" -> filteredList.sortByDescending { it.lastChapterDate } + "created_at" -> filteredList.sortByDescending { it.createdAt } + } + } + } + } + + val hasNextPage = filteredList.size > page * MANGAS_PER_PAGE + + return MangasPage( + filteredList.subList((page - 1) * MANGAS_PER_PAGE, min(page * MANGAS_PER_PAGE, filteredList.size)) + .map { it.toSimpleSManga() }, + hasNextPage, + ) + } + + override fun mangaDetailsParse(response: Response): SManga { + val responseBody = response.body.string() + val mangaDetailsJson = MANGA_DETAILS_REGEX.find(responseBody)?.groupValues?.get(1) + ?: throw Exception("No se pudo encontrar los detalles del manga") + val unescapedJson = mangaDetailsJson.replace("\\", "") + + val series = json.decodeFromString(unescapedJson) + return SManga.create().apply { + title = series.name + thumbnail_url = series.thumbnail + description = series.synopsis + genre = series.genders.joinToString { it.gender.name } + author = series.authors.joinToString { it.author.name } + artist = series.artists.joinToString { it.artist.name } + } + } + + override fun chapterListParse(response: Response): List { + val responseBody = response.body.string() + val mangaDetailsJson = MANGA_DETAILS_REGEX.find(responseBody)?.groupValues?.get(1) + ?: throw Exception("No se pudo encontrar la lista de capítulos") + val unescapedJson = mangaDetailsJson.replace("\\", "") + val series = json.decodeFromString(unescapedJson) + return series.chapters.map { chapter -> + SChapter.create().apply { + name = if (chapter.name.isNullOrBlank()) { + "Capítulo ${chapter.number.toString().removeSuffix(".0")}" + } else { + "Capítulo ${chapter.number.toString().removeSuffix(".0")} - ${chapter.name}" + } + date_upload = runCatching { dateFormat.parse(chapter.date)?.time }.getOrNull() ?: 0L + url = "/ver/${series.slug}/${chapter.slug}" + } + } + } + + override fun pageListParse(response: Response): List { + val document = response.asJsoup() + return document.select("main.contenedor.read img").mapIndexed { i, img -> + Page(i, "", img.imgAttr()) + } + } + + override fun getFilterList() = FilterList( + SortByFilter("Ordenar por", getSortProperties()), + StatusFilter(), + ) + + private fun getSortProperties(): List = listOf( + SortProperty("Nombre", "name"), + SortProperty("Visitas", "views"), + SortProperty("Actualización", "updated_at"), + SortProperty("Agregado", "created_at"), + ) + + data class SortProperty(val name: String, val value: String) { + override fun toString(): String = name + } + + class SortByFilter(title: String, private val sortProperties: List) : Filter.Sort( + title, + sortProperties.map { it.name }.toTypedArray(), + Selection(2, ascending = false), + ) { + val selected: String + get() = sortProperties[state!!.index].value + } + + private class StatusFilter : UriPartFilter( + "Estado", + arrayOf( + Pair("En emisión", 1), + Pair("En pausa", 2), + Pair("Abandonado", 3), + Pair("Finalizado", 4), + ), + ) + + private open class UriPartFilter(displayName: String, private val vals: Array>) : + Filter.Select(displayName, vals.map { it.first }.toTypedArray()) { + fun toUriPart() = vals[state].second + } + + private inline fun List<*>.firstInstanceOrNull(): R? = + filterIsInstance().firstOrNull() + + override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException() + + private fun Element.imgAttr(): String = when { + hasAttr("data-lazy-src") -> attr("abs:data-lazy-src") + hasAttr("data-src") -> attr("abs:data-src") + hasAttr("data-cfsrc") -> attr("abs:data-cfsrc") + else -> attr("abs:src") + } + + companion object { + private val MANGA_DETAILS_REGEX = """self.__next_f.push\(.*data\\":(\{.*lastChapters.*\}).*numFollow""".toRegex() + private const val MANGAS_PER_PAGE = 15 + } +} diff --git a/src/es/mangaesp/src/eu/kanade/tachiyomi/extension/es/mangaesp/MangaEspDto.kt b/src/es/mangaesp/src/eu/kanade/tachiyomi/extension/es/mangaesp/MangaEspDto.kt new file mode 100644 index 000000000..7be67694f --- /dev/null +++ b/src/es/mangaesp/src/eu/kanade/tachiyomi/extension/es/mangaesp/MangaEspDto.kt @@ -0,0 +1,91 @@ +package eu.kanade.tachiyomi.extension.es.mangaesp + +import eu.kanade.tachiyomi.source.model.SManga +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class TopSeriesDto( + val response: TopSeriesResponseDto, +) + +@Serializable +data class LastUpdatesDto( + val response: List, +) + +@Serializable +data class ComicsDto( + val response: List, +) + +@Serializable +data class TopSeriesResponseDto( + @SerialName("mensual") val topMonthly: List>, + @SerialName("semanal") val topWeekly: List>, + @SerialName("diario") val topDaily: List>, +) + +@Serializable +data class PayloadSeriesDto( + @SerialName("project") val data: SeriesDto, +) + +@Serializable +data class SeriesDto( + val name: String, + val slug: String, + @SerialName("sinopsis") val synopsis: String? = null, + @SerialName("urlImg") val thumbnail: String? = null, + val isVisible: Boolean, + @SerialName("actualizacionCap") val lastChapterDate: String? = null, + @SerialName("created_at") val createdAt: String? = null, + @SerialName("state_id") val status: Int? = 0, + val genders: List = emptyList(), + @SerialName("lastChapters") val chapters: List = emptyList(), + val trending: SeriesTrendingDto? = null, + @SerialName("autors") val authors: List = emptyList(), + val artists: List = emptyList(), + +) { + fun toSimpleSManga(): SManga { + return SManga.create().apply { + title = name + thumbnail_url = thumbnail + url = "/ver/$slug" + } + } +} + +@Serializable +data class SeriesTrendingDto( + @SerialName("visitas") val views: Int? = 0, +) + +@Serializable +data class SeriesGenderDto( + val gender: SeriesDetailDataNameDto, +) + +@Serializable +data class SeriesAuthorDto( + @SerialName("autor") val author: SeriesDetailDataNameDto, +) + +@Serializable +data class SeriesArtistDto( + val artist: SeriesDetailDataNameDto, +) + +@Serializable +data class SeriesDetailDataNameDto( + val name: String, +) + +@Serializable +data class SeriesChapterDto( + @SerialName("num") val number: Float, + val name: String? = null, + val slug: String, + @SerialName("created_at") val date: String, +)