Add a new source to MangaSar (#13089)

* Add a new source to MangaSar.

* Remove unused imports.
This commit is contained in:
Alessandro Jean 2022-08-19 20:52:00 -03:00 committed by GitHub
parent 131394800f
commit db666a6798
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 52 additions and 45 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

View File

@ -1,18 +0,0 @@
package eu.kanade.tachiyomi.extension.pt.mangatube
import eu.kanade.tachiyomi.multisrc.mangasar.MangaSar
import eu.kanade.tachiyomi.network.interceptor.rateLimit
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)
.rateLimit(1, 2, TimeUnit.SECONDS)
.build()
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.extension.pt.mangazim
import eu.kanade.tachiyomi.multisrc.mangasar.MangaSar
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Element
class Mangazim : MangaSar("Mangazim", "https://mangazim.com", "pt-BR") {
override fun chapterListPaginatedRequest(mangaUrl: String, page: Int): Request {
return GET(baseUrl + mangaUrl, headers)
}
override fun chapterListParse(response: Response): List<SChapter> {
return response.asJsoup()
.select("ul.full-chapters-list > li > a")
.map(::chapterFromElement)
}
private fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
name = element.selectFirst("span.cap-text")!!.text()
date_upload = element.selectFirst("span.chapter-date")?.text()?.toDate() ?: 0L
setUrlWithoutDomain(element.attr("href"))
}
}

View File

@ -2,16 +2,13 @@ package eu.kanade.tachiyomi.extension.pt.meusmangas
import eu.kanade.tachiyomi.multisrc.mangasar.MangaSar import eu.kanade.tachiyomi.multisrc.mangasar.MangaSar
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.util.concurrent.TimeUnit
class MeusMangas : MangaSar( class MeusMangas : MangaSar(
"Meus Mangás", "Meus Mangás",
@ -19,11 +16,6 @@ class MeusMangas : MangaSar(
"pt-BR" "pt-BR"
) { ) {
override val client: OkHttpClient = super.client.newBuilder()
.addInterceptor(::searchIntercept)
.rateLimit(1, 2, TimeUnit.SECONDS)
.build()
override fun popularMangaSelector() = "ul.sidebar-popular li.popular-treending" override fun popularMangaSelector() = "ul.sidebar-popular li.popular-treending"
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply { override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.multisrc.mangasar
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
@ -29,6 +30,7 @@ import uy.kohesive.injekt.injectLazy
import java.text.ParseException import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.concurrent.TimeUnit
abstract class MangaSar( abstract class MangaSar(
override val name: String, override val name: String,
@ -38,7 +40,10 @@ abstract class MangaSar(
override val supportsLatest = true override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.addInterceptor(::searchIntercept)
.rateLimit(1, 2, TimeUnit.SECONDS)
.build()
override fun headersBuilder(): Headers.Builder = Headers.Builder() override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("Accept", ACCEPT_HTML) .add("Accept", ACCEPT_HTML)
@ -51,7 +56,7 @@ abstract class MangaSar(
private val apiHeaders: Headers by lazy { apiHeadersBuilder().build() } private val apiHeaders: Headers by lazy { apiHeadersBuilder().build() }
private val json: Json by injectLazy() protected val json: Json by injectLazy()
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
return GET(baseUrl, headers) return GET(baseUrl, headers)
@ -89,7 +94,7 @@ abstract class MangaSar(
} }
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
val result = json.decodeFromString<MangaSarLatestDto>(response.body!!.string()) val result = response.parseAs<MangaSarLatestDto>()
val latestMangas = result.releases val latestMangas = result.releases
.map(::latestUpdatesFromObject) .map(::latestUpdatesFromObject)
@ -116,7 +121,7 @@ abstract class MangaSar(
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val result = json.decodeFromString<Map<String, MangaSarTitleDto>>(response.body!!.string()) val result = response.parseAs<Map<String, MangaSarTitleDto>>()
val searchResults = result.values.map(::searchMangaFromObject) val searchResults = result.values.map(::searchMangaFromObject)
@ -131,12 +136,12 @@ abstract class MangaSar(
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val document = response.asJsoup() val document = response.asJsoup()
val infoElement = document.select("div.manga-single div.dados").first() val infoElement = document.selectFirst("div.manga-single div.dados")!!
return SManga.create().apply { return SManga.create().apply {
title = infoElement.select("h1").first()!!.text() title = infoElement.selectFirst("h1")!!.text()
thumbnail_url = infoElement.select("div.thumb img").first()!!.attr("abs:src") thumbnail_url = infoElement.selectFirst("div.thumb img")!!.attr("abs:src")
description = infoElement.select("div.sinopse").first()!!.text() description = infoElement.selectFirst("div.sinopse")!!.text()
genre = infoElement.select("ul.generos li a span.button").joinToString { it.text() } genre = infoElement.select("ul.generos li a span.button").joinToString { it.text() }
} }
} }
@ -162,7 +167,7 @@ abstract class MangaSar(
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val mangaUrl = response.request.header("Referer")!!.substringAfter(baseUrl) val mangaUrl = response.request.header("Referer")!!.substringAfter(baseUrl)
var result = json.decodeFromString<MangaSarPaginatedChaptersDto>(response.body!!.string()) var result = response.parseAs<MangaSarPaginatedChaptersDto>()
if (result.chapters.isNullOrEmpty()) { if (result.chapters.isNullOrEmpty()) {
return emptyList() return emptyList()
@ -177,9 +182,7 @@ abstract class MangaSar(
while (++page <= lastPage!!) { while (++page <= lastPage!!) {
val nextPageRequest = chapterListPaginatedRequest(mangaUrl, page) val nextPageRequest = chapterListPaginatedRequest(mangaUrl, page)
result = client.newCall(nextPageRequest).execute().let { result = client.newCall(nextPageRequest).execute().parseAs()
json.decodeFromString(it.body!!.string())
}
chapters += result.chapters!! chapters += result.chapters!!
.map(::chapterFromObject) .map(::chapterFromObject)
@ -212,8 +215,8 @@ abstract class MangaSar(
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup() val document = response.asJsoup()
val apiParams = document.select("script:containsData(id_serie)").firstOrNull() val apiParams = document.selectFirst("script:containsData(id_serie)")?.data()
?.data() ?: throw Exception(TOKEN_NOT_FOUND) ?: throw Exception(TOKEN_NOT_FOUND)
val chapterUrl = response.request.url.toString() val chapterUrl = response.request.url.toString()
val serieId = apiParams.substringAfter("\"") val serieId = apiParams.substringAfter("\"")
@ -221,9 +224,7 @@ abstract class MangaSar(
val token = TOKEN_REGEX.find(apiParams)!!.groupValues[1] val token = TOKEN_REGEX.find(apiParams)!!.groupValues[1]
val apiRequest = pageListApiRequest(chapterUrl, serieId, token) val apiRequest = pageListApiRequest(chapterUrl, serieId, token)
val apiResponse = client.newCall(apiRequest).execute().let { val apiResponse = client.newCall(apiRequest).execute().parseAs<MangaSarReaderDto>()
json.decodeFromString<MangaSarReaderDto>(it.body!!.string())
}
return apiResponse.images return apiResponse.images
.filter { it.url.startsWith("http") } .filter { it.url.startsWith("http") }
@ -268,6 +269,10 @@ abstract class MangaSar(
return chain.proceed(chain.request()) return chain.proceed(chain.request())
} }
protected inline fun <reified T> Response.parseAs(): T = use {
json.decodeFromString(body?.string().orEmpty())
}
protected fun String.toDate(): Long { protected fun String.toDate(): Long {
return try { return try {
DATE_FORMATTER.parse(this)?.time ?: 0L DATE_FORMATTER.parse(this)?.time ?: 0L

View File

@ -9,10 +9,10 @@ class MangaSarGenerator : ThemeSourceGenerator {
override val themeClass = "MangaSar" override val themeClass = "MangaSar"
override val baseVersionCode: Int = 6 override val baseVersionCode: Int = 7
override val sources = listOf( override val sources = listOf(
SingleLang("MangaTube", "https://mangatube.site", "pt-BR"), SingleLang("Mangazim", "https://mangazim.com", "pt-BR"),
SingleLang("Meus Mangás", "https://meusmangas.net", "pt-BR", isNsfw = true, className = "MeusMangas", overrideVersionCode = 2) SingleLang("Meus Mangás", "https://meusmangas.net", "pt-BR", isNsfw = true, className = "MeusMangas", overrideVersionCode = 2)
) )