Move MT to multisrc and add a new source. (#8478)

This commit is contained in:
Alessandro Jean 2021-08-09 07:58:15 -03:00 committed by GitHub
parent b4a80e6085
commit ab8ea9ddb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 138 additions and 56 deletions

View File

@ -0,0 +1,4 @@
dependencies {
implementation project(':lib-ratelimit')
}

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,18 @@
package eu.kanade.tachiyomi.extension.pt.mangatube
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.multisrc.mangasar.MangaSar
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit
class MangaTube : MangaSar(
"MangaTube",
"https://mangatube.site",
"pt-BR"
) {
override val client: OkHttpClient = super.client.newBuilder()
.addInterceptor(::searchIntercept)
.addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
.build()
}

View File

@ -0,0 +1,52 @@
package eu.kanade.tachiyomi.extension.pt.meusmangas
import eu.kanade.tachiyomi.annotations.Nsfw
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.multisrc.mangasar.MangaSar
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
import okhttp3.Response
import org.jsoup.nodes.Element
import java.util.concurrent.TimeUnit
@Nsfw
class MeusMangas : MangaSar(
"Meus Mangás",
"https://meusmangas.net",
"pt-BR"
) {
override val client: OkHttpClient = super.client.newBuilder()
.addInterceptor(::searchIntercept)
.addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
.build()
override fun popularMangaSelector() = "ul.sidebar-popular li.popular-treending"
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
title = element.selectFirst("h4.title").text()
thumbnail_url = element.selectFirst("div.tumbl img").attr("src")
setUrlWithoutDomain(element.selectFirst("a").attr("abs:href"))
}
override fun mangaDetailsParse(response: Response): SManga {
val document = response.asJsoup()
val infoElement = document.selectFirst("div.box-single:has(div.mangapage)")
return SManga.create().apply {
title = infoElement.selectFirst("h1.kw-title").text()
author = infoElement.selectFirst("div.mdq.author").text().trim()
description = infoElement.selectFirst("div.sinopse-page").text()
genre = infoElement.select("div.touchcarousel a.widget-btn").joinToString { it.text() }
status = infoElement.selectFirst("span.mdq").text().toStatus()
thumbnail_url = infoElement.selectFirst("div.thumb img").attr("abs:src")
}
}
private fun String.toStatus(): Int = when (this) {
"Em andamento" -> SManga.ONGOING
"Completo" -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
}

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.extension.pt.mangatube
package eu.kanade.tachiyomi.multisrc.mangasar
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.source.model.FilterList
@ -24,27 +23,22 @@ import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Element
import org.jsoup.parser.Parser
import rx.Observable
import uy.kohesive.injekt.injectLazy
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.concurrent.TimeUnit
class MangaTube : HttpSource() {
override val name = "MangaTube"
override val baseUrl = "https://mangatube.site"
override val lang = "pt-BR"
abstract class MangaSar(
override val name: String,
override val baseUrl: String,
override val lang: String
) : HttpSource() {
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
.addInterceptor(::searchIntercept)
.build()
override val client: OkHttpClient = network.cloudflareClient
override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("Accept", ACCEPT_HTML)
@ -66,13 +60,16 @@ class MangaTube : HttpSource() {
override fun popularMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangas = document.select("div:contains(Populares) ~ ul.mangasList li div.gridbox")
val mangas = document.select(popularMangaSelector())
.map(::popularMangaFromElement)
return MangasPage(mangas, hasNextPage = false)
}
private fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
protected open fun popularMangaSelector(): String =
"div:contains(Populares) ~ ul.mangasList li div.gridbox"
protected open fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
title = element.select("div.title a").first()!!.text()
thumbnail_url = element.select("div.thumb img").first()!!.attr("abs:src")
setUrlWithoutDomain(element.select("a").first()!!.attr("href"))
@ -92,18 +89,19 @@ class MangaTube : HttpSource() {
}
override fun latestUpdatesParse(response: Response): MangasPage {
val result = json.decodeFromString<MangaTubeLatestDto>(response.body!!.string())
val result = json.decodeFromString<MangaSarLatestDto>(response.body!!.string())
val latestMangas = result.releases
.map(::latestUpdatesFromObject)
.distinctBy { it.url }
val hasNextPage = result.page.toInt() < result.totalPage
return MangasPage(latestMangas, hasNextPage)
}
private fun latestUpdatesFromObject(release: MangaTubeReleaseDto) = SManga.create().apply {
title = release.name
private fun latestUpdatesFromObject(release: MangaSarReleaseDto) = SManga.create().apply {
title = release.name.withoutEntities()
thumbnail_url = release.image
url = release.link
}
@ -118,14 +116,14 @@ class MangaTube : HttpSource() {
}
override fun searchMangaParse(response: Response): MangasPage {
val result = json.decodeFromString<Map<String, MangaTubeTitleDto>>(response.body!!.string())
val result = json.decodeFromString<Map<String, MangaSarTitleDto>>(response.body!!.string())
val searchResults = result.values.map(::searchMangaFromObject)
return MangasPage(searchResults, hasNextPage = false)
}
private fun searchMangaFromObject(manga: MangaTubeTitleDto) = SManga.create().apply {
private fun searchMangaFromObject(manga: MangaSarTitleDto) = SManga.create().apply {
title = manga.title
thumbnail_url = manga.image
setUrlWithoutDomain(manga.url)
@ -164,7 +162,7 @@ class MangaTube : HttpSource() {
override fun chapterListParse(response: Response): List<SChapter> {
val mangaUrl = response.request.header("Referer")!!.substringAfter(baseUrl)
var result = json.decodeFromString<MangaTubePaginatedChaptersDto>(response.body!!.string())
var result = json.decodeFromString<MangaSarPaginatedChaptersDto>(response.body!!.string())
if (result.chapters.isNullOrEmpty()) {
return emptyList()
@ -191,7 +189,7 @@ class MangaTube : HttpSource() {
return chapters
}
private fun chapterFromObject(chapter: MangaTubeChapterDto): SChapter = SChapter.create().apply {
private fun chapterFromObject(chapter: MangaSarChapterDto): SChapter = SChapter.create().apply {
name = "Cap. " + (if (chapter.number.booleanOrNull != null) "0" else chapter.number.content) +
(if (chapter.name.isString) " - " + chapter.name.content else "")
chapter_number = chapter.number.floatOrNull ?: -1f
@ -224,7 +222,7 @@ class MangaTube : HttpSource() {
val apiRequest = pageListApiRequest(chapterUrl, serieId, token)
val apiResponse = client.newCall(apiRequest).execute().let {
json.decodeFromString<MangaTubeReaderDto>(it.body!!.string())
json.decodeFromString<MangaSarReaderDto>(it.body!!.string())
}
return apiResponse.images
@ -245,7 +243,7 @@ class MangaTube : HttpSource() {
return GET(page.imageUrl!!, newHeaders)
}
private fun searchIntercept(chain: Interceptor.Chain): Response {
protected fun searchIntercept(chain: Interceptor.Chain): Response {
if (chain.request().url.toString().contains("/search/")) {
val homeRequest = popularMangaRequest(1)
val document = chain.proceed(homeRequest).asJsoup()
@ -278,6 +276,10 @@ class MangaTube : HttpSource() {
}
}
private fun String.withoutEntities(): String {
return Parser.unescapeEntities(this, true)
}
companion object {
private const val ACCEPT = "application/json, text/plain, */*"
private const val ACCEPT_HTML = "text/html,application/xhtml+xml,application/xml;q=0.9," +

View File

@ -1,39 +1,39 @@
package eu.kanade.tachiyomi.extension.pt.mangatube
package eu.kanade.tachiyomi.multisrc.mangasar
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonPrimitive
@Serializable
data class MangaTubeLatestDto(
data class MangaSarLatestDto(
val page: String,
val releases: List<MangaTubeReleaseDto> = emptyList(),
val releases: List<MangaSarReleaseDto> = emptyList(),
@SerialName("total_page") val totalPage: Int
)
@Serializable
data class MangaTubeReleaseDto(
data class MangaSarReleaseDto(
val image: String,
val link: String,
val name: String
)
@Serializable
data class MangaTubeTitleDto(
data class MangaSarTitleDto(
@SerialName("img") val image: String,
val title: String,
val url: String
)
@Serializable
data class MangaTubePaginatedChaptersDto(
val chapters: List<MangaTubeChapterDto>? = emptyList(),
data class MangaSarPaginatedChaptersDto(
val chapters: List<MangaSarChapterDto>? = emptyList(),
@SerialName("pagina") val page: Int,
@SerialName("total_pags") val totalPages: Int
)
@Serializable
data class MangaTubeChapterDto(
data class MangaSarChapterDto(
@SerialName("date_created") val dateCreated: String,
val link: String,
@SerialName("chapter_name") val name: JsonPrimitive,
@ -41,11 +41,11 @@ data class MangaTubeChapterDto(
)
@Serializable
data class MangaTubeReaderDto(
val images: List<MangaTubePageDto> = emptyList()
data class MangaSarReaderDto(
val images: List<MangaSarPageDto> = emptyList()
)
@Serializable
data class MangaTubePageDto(
data class MangaSarPageDto(
val url: String
)

View File

@ -0,0 +1,26 @@
package eu.kanade.tachiyomi.multisrc.mangasar
import generator.ThemeSourceData.SingleLang
import generator.ThemeSourceGenerator
class MangaSarGenerator : ThemeSourceGenerator {
override val themePkg = "mangasar"
override val themeClass = "MangaSar"
override val baseVersionCode: Int = 4
override val sources = listOf(
SingleLang("MangaTube", "https://mangatube.site", "pt-BR"),
SingleLang("Meus Mangás", "https://meusmangas.net", "pt-BR", isNsfw = true, className = "MeusMangas")
)
companion object {
@JvmStatic
fun main(args: Array<String>) {
MangaSarGenerator().createAll()
}
}
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.extension" />

View File

@ -1,18 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
ext {
extName = 'MangaTube'
pkgNameSuffix = 'pt.mangatube'
extClass = '.MangaTube'
extVersionCode = 3
libVersion = '1.2'
}
dependencies {
implementation project(':lib-ratelimit')
}
apply from: "$rootDir/common.gradle"