diff --git a/src/pt/hqdragon/AndroidManifest.xml b/src/pt/hqdragon/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/pt/hqdragon/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/pt/hqdragon/build.gradle b/src/pt/hqdragon/build.gradle
deleted file mode 100644
index 8eb08a8e7..000000000
--- a/src/pt/hqdragon/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-
-ext {
- extName = 'HQ Dragon'
- pkgNameSuffix = 'pt.hqdragon'
- extClass = '.HQDragon'
- extVersionCode = 4
- libVersion = '1.2'
-}
-
-dependencies {
- implementation project(':lib-ratelimit')
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/pt/hqdragon/res/mipmap-hdpi/ic_launcher.png b/src/pt/hqdragon/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 7c21d8b91..000000000
Binary files a/src/pt/hqdragon/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/hqdragon/res/mipmap-mdpi/ic_launcher.png b/src/pt/hqdragon/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 04df4fb73..000000000
Binary files a/src/pt/hqdragon/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/hqdragon/res/mipmap-xhdpi/ic_launcher.png b/src/pt/hqdragon/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 2d51d19fa..000000000
Binary files a/src/pt/hqdragon/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/hqdragon/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/hqdragon/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index de7b1a1cf..000000000
Binary files a/src/pt/hqdragon/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/hqdragon/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/hqdragon/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 5ea6265cd..000000000
Binary files a/src/pt/hqdragon/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/hqdragon/res/web_hi_res_512.png b/src/pt/hqdragon/res/web_hi_res_512.png
deleted file mode 100644
index 3992c579d..000000000
Binary files a/src/pt/hqdragon/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/pt/hqdragon/src/eu/kanade/tachiyomi/extension/pt/hqdragon/HQDragon.kt b/src/pt/hqdragon/src/eu/kanade/tachiyomi/extension/pt/hqdragon/HQDragon.kt
deleted file mode 100644
index 5bf24977b..000000000
--- a/src/pt/hqdragon/src/eu/kanade/tachiyomi/extension/pt/hqdragon/HQDragon.kt
+++ /dev/null
@@ -1,206 +0,0 @@
-package eu.kanade.tachiyomi.extension.pt.hqdragon
-
-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
-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.ParsedHttpSource
-import okhttp3.FormBody
-import okhttp3.Headers
-import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import org.jsoup.nodes.Document
-import org.jsoup.nodes.Element
-import rx.Observable
-import java.util.concurrent.TimeUnit
-
-class HQDragon : ParsedHttpSource() {
-
- override val name = "HQ Dragon"
-
- override val baseUrl = "https://hqdragon.com"
-
- override val lang = "pt-BR"
-
- override val supportsLatest = true
-
- override val client: OkHttpClient = network.cloudflareClient.newBuilder()
- .addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
- .build()
-
- override fun headersBuilder(): Headers.Builder = Headers.Builder()
- .add("Accept", ACCEPT)
- .add("Accept-Language", ACCEPT_LANGUAGE)
- .add("Referer", "$baseUrl/")
-
- // Popular
-
- // Top 10
- override fun popularMangaRequest(page: Int): Request {
- return GET(baseUrl, headers)
- }
-
- override fun popularMangaParse(response: Response): MangasPage {
- val results = super.popularMangaParse(response)
-
- if (results.mangas.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return results
- }
-
- override fun popularMangaSelector() = "h4:contains(Top 10) + ol.mb-0 li a"
-
- override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
- title = element.text()
- setUrlWithoutDomain(element.attr("href"))
- }
-
- override fun popularMangaNextPageSelector(): String? = null
-
- // Latest
-
- override fun fetchLatestUpdates(page: Int): Observable {
- return super.fetchLatestUpdates(page)
- .map { results -> results.copy(hasNextPage = page < 5) }
- }
-
- override fun latestUpdatesRequest(page: Int): Request {
- val formBody = FormBody.Builder()
- .add("pagina", page.toString())
- .build()
-
- val headers = headersBuilder()
- .add("Content-Length", formBody.contentLength().toString())
- .add("Content-Type", formBody.contentType().toString())
- .add("Origin", baseUrl)
- .add("X-Requested-With", "XMLHttpRequest")
- .set("Accept", "*/*")
- .build()
-
- return POST("$baseUrl/assets/php/index_paginar.php", headers, formBody)
- }
-
- override fun latestUpdatesParse(response: Response): MangasPage {
- val results = super.latestUpdatesParse(response)
-
- if (results.mangas.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return results
- }
-
- override fun latestUpdatesSelector() = "a:has(img)"
-
- override fun latestUpdatesFromElement(element: Element): SManga = SManga.create().apply {
- val image = element.select("img").first()
-
- title = image.attr("alt")
- thumbnail_url = image.attr("abs:src")
- setUrlWithoutDomain(element.attr("href"))
- }
-
- override fun latestUpdatesNextPageSelector(): String? = null
-
- // Search
-
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
- val url = "$baseUrl/pesquisa".toHttpUrlOrNull()!!.newBuilder()
- .addQueryParameter("titulo", query)
-
- return GET(url.toString(), headers)
- }
-
- override fun searchMangaParse(response: Response): MangasPage {
- val results = super.searchMangaParse(response)
-
- if (results.mangas.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return results
- }
-
- override fun searchMangaSelector() = "div.col-sm-6.col-md-3:has(img.img-thumbnail)"
-
- override fun searchMangaFromElement(element: Element): SManga = SManga.create().apply {
- val link = element.select("a + a").first()
-
- title = link.text()
- thumbnail_url = element.select("img").first().attr("abs:src")
- setUrlWithoutDomain(link.attr("href"))
- }
-
- override fun searchMangaNextPageSelector(): String? = null
-
- // Manga summary page
-
- override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
- val infoElement = document.select("div.blog-post div.row").firstOrNull()
- ?: throw Exception(BLOCK_MESSAGE)
-
- title = infoElement.select("h3").first().text()
- author = infoElement.select("p:contains(Editora:)").first().textWithoutLabel()
- status = infoElement.select("p:contains(Status:) span").first().text().toStatus()
- description = infoElement.select("p:contains(Sinopse:)").first().ownText()
- thumbnail_url = infoElement.select("div.col-md-4 .img-fluid").first().attr("src")
- }
-
- // Chapters
-
- override fun chapterListSelector() = "table.table tr a"
-
- override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
- name = element.text().replace("Ler ", "")
- setUrlWithoutDomain(element.attr("href"))
- }
-
- // Pages
-
- override fun pageListParse(document: Document): List {
- return document.select("img.img-responsive.img-manga")
- .filter { it.attr("src").contains("/leitor/") }
- .mapIndexed { i, element ->
- Page(i, document.location(), element.absUrl("src"))
- }
- }
-
- override fun imageUrlParse(document: Document) = ""
-
- override fun imageRequest(page: Page): Request {
- val newHeaders = headersBuilder()
- .set("Accept", ACCEPT_IMAGE)
- .set("Referer", page.url)
- .build()
-
- return GET(page.imageUrl!!, newHeaders)
- }
-
- private fun Element.textWithoutLabel(): String = text()!!.substringAfter(":").trim()
-
- private fun String.toStatus(): Int = when {
- contains("Ativo") -> SManga.ONGOING
- contains("Completo") -> SManga.COMPLETED
- else -> SManga.UNKNOWN
- }
-
- companion object {
- private const val ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9," +
- "image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
- private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
- private const val ACCEPT_LANGUAGE = "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6,gl;q=0.5"
- private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
- "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36"
-
- private const val BLOCK_MESSAGE = "O site está bloqueando o Tachiyomi. " +
- "Migre para outra fonte caso o problema persistir."
- }
-}
diff --git a/src/pt/mangahost/AndroidManifest.xml b/src/pt/mangahost/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/pt/mangahost/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/pt/mangahost/build.gradle b/src/pt/mangahost/build.gradle
deleted file mode 100644
index 944d148d4..000000000
--- a/src/pt/mangahost/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-
-ext {
- extName = 'Mangá Host'
- pkgNameSuffix = 'pt.mangahost'
- extClass = '.MangaHost'
- extVersionCode = 24
- libVersion = '1.2'
-}
-
-dependencies {
- implementation project(':lib-ratelimit')
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/pt/mangahost/res/mipmap-hdpi/ic_launcher.png b/src/pt/mangahost/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index eaf86b0f2..000000000
Binary files a/src/pt/mangahost/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/mangahost/res/mipmap-mdpi/ic_launcher.png b/src/pt/mangahost/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index dfcf87577..000000000
Binary files a/src/pt/mangahost/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/mangahost/res/mipmap-xhdpi/ic_launcher.png b/src/pt/mangahost/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index b2b7a89ea..000000000
Binary files a/src/pt/mangahost/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/mangahost/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/mangahost/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index a220903e1..000000000
Binary files a/src/pt/mangahost/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/mangahost/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/mangahost/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 70558e895..000000000
Binary files a/src/pt/mangahost/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/mangahost/res/web_hi_res_512.png b/src/pt/mangahost/res/web_hi_res_512.png
deleted file mode 100644
index e7a9e90e3..000000000
Binary files a/src/pt/mangahost/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/pt/mangahost/src/eu/kanade/tachiyomi/extension/pt/mangahost/MangaHost.kt b/src/pt/mangahost/src/eu/kanade/tachiyomi/extension/pt/mangahost/MangaHost.kt
deleted file mode 100644
index eee79f0e8..000000000
--- a/src/pt/mangahost/src/eu/kanade/tachiyomi/extension/pt/mangahost/MangaHost.kt
+++ /dev/null
@@ -1,288 +0,0 @@
-package eu.kanade.tachiyomi.extension.pt.mangahost
-
-import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.network.asObservable
-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.ParsedHttpSource
-import okhttp3.Call
-import okhttp3.Headers
-import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
-import okhttp3.Interceptor
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import org.jsoup.nodes.Document
-import org.jsoup.nodes.Element
-import org.jsoup.select.Elements
-import rx.Observable
-import java.text.ParseException
-import java.text.SimpleDateFormat
-import java.util.Locale
-import java.util.concurrent.TimeUnit
-
-class MangaHost : ParsedHttpSource() {
-
- // Hardcode the id because the name was wrong and the language wasn't specific.
- override val id: Long = 3926812845500643354
-
- override val name = "Mangá Host"
-
- override val baseUrl = "https://mangahostz.com"
-
- override val lang = "pt-BR"
-
- override val supportsLatest = true
-
- override val client: OkHttpClient = network.cloudflareClient.newBuilder()
- .addInterceptor(RateLimitInterceptor(1, 3, TimeUnit.SECONDS))
- .addInterceptor(::blockMessageIntercept)
- .build()
-
- override fun headersBuilder(): Headers.Builder = Headers.Builder()
- .add("Accept", ACCEPT)
- .add("Accept-Language", ACCEPT_LANGUAGE)
- .add("Referer", baseUrl)
- .add("User-Agent", USER_AGENT)
-
- private fun genericMangaFromElement(element: Element): SManga = SManga.create().apply {
- val thumbnailEl = element.select("img")
- val thumbnailAttr = if (thumbnailEl.hasAttr("data-path")) "data-path" else "src"
-
- title = element.attr("title").withoutLanguage()
- thumbnail_url = thumbnailEl.attr(thumbnailAttr).toLargeUrl()
- setUrlWithoutDomain(element.attr("href"))
- }
-
- override fun popularMangaRequest(page: Int): Request {
- val listPath = if (page == 1) "" else "/mais-visualizados/page/${page - 1}"
- val newHeaders = headersBuilder()
- .set("Referer", "$baseUrl/mangas$listPath")
- .build()
-
- val pageStr = if (page != 1) "/page/$page" else ""
- return GET("$baseUrl/mangas/mais-visualizados$pageStr", newHeaders)
- }
-
- override fun popularMangaParse(response: Response): MangasPage {
- val results = super.popularMangaParse(response)
-
- if (results.mangas.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return results
- }
-
- override fun popularMangaSelector(): String = "div#dados div.manga-block div.manga-block-left a"
-
- override fun popularMangaFromElement(element: Element): SManga = genericMangaFromElement(element)
-
- override fun popularMangaNextPageSelector() = "div.wp-pagenavi:has(a.nextpostslink)"
-
- override fun latestUpdatesRequest(page: Int): Request {
- val listPath = if (page == 1) "" else "/lancamentos/page/${page - 1}"
- val newHeaders = headersBuilder()
- .set("Referer", baseUrl + listPath)
- .build()
-
- val pageStr = if (page != 1) "/page/$page" else ""
- return GET("$baseUrl/lancamentos$pageStr", newHeaders)
- }
-
- override fun latestUpdatesParse(response: Response): MangasPage {
- val results = super.latestUpdatesParse(response)
-
- if (results.mangas.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return results
- }
-
- override fun latestUpdatesSelector() = "div#dados div.w-row div.column-img a"
-
- override fun latestUpdatesFromElement(element: Element): SManga = genericMangaFromElement(element)
-
- override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
-
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
- val url = "$baseUrl/find".toHttpUrlOrNull()!!.newBuilder()
- .addQueryParameter("this", query)
-
- return GET(url.toString(), headers)
- }
-
- override fun searchMangaSelector() = "table.table-search > tbody > tr > td:eq(0) > a"
-
- override fun searchMangaFromElement(element: Element): SManga = genericMangaFromElement(element)
-
- override fun searchMangaNextPageSelector(): String? = null
-
- /**
- * The site wrongly return 404 for some titles, even if they are present.
- * In those cases, the extension will parse the response normally.
- */
- override fun fetchMangaDetails(manga: SManga): Observable {
- return client.newCall(mangaDetailsRequest(manga))
- .asObservableIgnoreCode(404)
- .map { response ->
- mangaDetailsParse(response).apply { initialized = true }
- }
- }
-
- override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
- val infoElement = document.select("div.box-content div.w-row div.w-col:eq(1) article")
- .firstOrNull() ?: throw Exception(BLOCK_MESSAGE)
-
- author = infoElement.select("div.text li div:contains(Autor:)").textWithoutLabel()
- artist = infoElement.select("div.text li div:contains(Arte:)").textWithoutLabel()
- genre = infoElement.select("h3.subtitle + div.tags a").joinToString { it.text() }
- description = infoElement.select("div.text div.paragraph").first()?.text()
- ?.substringBefore("Relacionados:")
- status = infoElement.select("div.text li div:contains(Status:)").text().toStatus()
- thumbnail_url = document.select("div.box-content div.w-row div.w-col:eq(0) div.widget img")
- .attr("src")
- }
-
- /**
- * The site wrongly return 404 for some titles, even if they are present.
- * In those cases, the extension will parse the response normally.
- */
- override fun fetchChapterList(manga: SManga): Observable> {
- return if (manga.status != SManga.LICENSED) {
- client.newCall(chapterListRequest(manga))
- .asObservableIgnoreCode(404)
- .map(::chapterListParse)
- } else {
- Observable.error(Exception("Licensed - No chapters to show"))
- }
- }
-
- override fun chapterListParse(response: Response): List {
- val chapters = super.chapterListParse(response)
-
- if (chapters.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return chapters
- }
-
- override fun chapterListSelector(): String =
- "article section.clearfix div.chapters div.cap div.card.pop"
-
- override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
- name = element.select("div.pop-title").text().withoutLanguage()
- scanlator = element.select("div.pop-content small strong").text()
- date_upload = element.select("small.clearfix").text()
- .substringAfter("Adicionado em ")
- .toDate()
- chapter_number = element.select("div.pop-title span.btn-caps").text()
- .toFloatOrNull() ?: 1f
- setUrlWithoutDomain(element.select("div.tags a").attr("href"))
-
- if (scanlator!!.split("/").count() >= 5) {
- val scanlators = scanlator!!.split("/")
- scanlator = scanlators[0] + " e mais " + (scanlators.count() - 1)
- }
- }
-
- /**
- * The site wrongly return 404 for some chapters, even if they are present.
- * In those cases, the extension will parse the response normally.
- */
- override fun fetchPageList(chapter: SChapter): Observable> {
- return client.newCall(pageListRequest(chapter))
- .asObservableIgnoreCode(404)
- .map(::pageListParse)
- }
-
- override fun pageListRequest(chapter: SChapter): Request {
- // Just to prevent the detection of the crawler.
- val newHeader = headersBuilder()
- .set("Referer", "$baseUrl${chapter.url}".substringBeforeLast("/"))
- .build()
-
- return GET(baseUrl + chapter.url, newHeader)
- }
-
- override fun pageListParse(document: Document): List {
- return document.select("div#slider a img")
- .mapIndexed { i, el -> Page(i, document.location(), el.attr("src")) }
- }
-
- override fun imageUrlParse(document: Document) = ""
-
- override fun imageRequest(page: Page): Request {
- val newHeaders = headersBuilder()
- .set("Accept", ACCEPT_IMAGE)
- .set("Referer", "$baseUrl/")
- .build()
-
- return GET(page.imageUrl!!, newHeaders)
- }
-
- private fun blockMessageIntercept(chain: Interceptor.Chain): Response {
- val response = chain.proceed(chain.request())
-
- if (response.code == 403 || response.code == 1020) {
- response.close()
- throw Exception(BLOCK_MESSAGE)
- }
-
- return response
- }
-
- private fun Call.asObservableIgnoreCode(code: Int): Observable {
- return asObservable().doOnNext { response ->
- if (!response.isSuccessful && response.code != code) {
- response.close()
- throw Exception("HTTP error ${response.code}")
- }
- }
- }
-
- private fun String.toDate(): Long {
- return try {
- DATE_FORMAT.parse(this)?.time ?: 0L
- } catch (e: ParseException) {
- 0L
- }
- }
-
- private fun String.toStatus() = when (this) {
- "Ativo" -> SManga.ONGOING
- "Completo" -> SManga.COMPLETED
- else -> SManga.UNKNOWN
- }
-
- private fun String.withoutLanguage(): String = replace(LANG_REGEX, "")
-
- private fun String.toLargeUrl(): String = replace(IMAGE_REGEX, "_full.")
-
- private fun Elements.textWithoutLabel(): String = text()!!.substringAfter(":").trim()
-
- companion object {
- private const val ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9," +
- "image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
- private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
- private const val ACCEPT_LANGUAGE = "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6,gl;q=0.5"
- private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
- "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
-
- private val LANG_REGEX = "( )?\\((PT-)?BR\\)".toRegex()
- private val IMAGE_REGEX = "_(small|medium|xmedium)\\.".toRegex()
-
- private const val BLOCK_MESSAGE = "O site está bloqueando o Tachiyomi. " +
- "Migre para outra fonte caso o problema persistir."
-
- private val DATE_FORMAT by lazy {
- SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH)
- }
- }
-}
diff --git a/src/pt/unionmangas/AndroidManifest.xml b/src/pt/unionmangas/AndroidManifest.xml
deleted file mode 100644
index f7d3a86a3..000000000
--- a/src/pt/unionmangas/AndroidManifest.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/pt/unionmangas/build.gradle b/src/pt/unionmangas/build.gradle
deleted file mode 100644
index 29edc5641..000000000
--- a/src/pt/unionmangas/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-
-ext {
- extName = 'Union Mangás'
- pkgNameSuffix = 'pt.unionmangas'
- extClass = '.UnionMangas'
- extVersionCode = 22
- libVersion = '1.2'
-}
-
-dependencies {
- implementation project(':lib-ratelimit')
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/pt/unionmangas/res/mipmap-hdpi/ic_launcher.png b/src/pt/unionmangas/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 1b71ad135..000000000
Binary files a/src/pt/unionmangas/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/unionmangas/res/mipmap-mdpi/ic_launcher.png b/src/pt/unionmangas/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 5f08eb5c0..000000000
Binary files a/src/pt/unionmangas/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/unionmangas/res/mipmap-xhdpi/ic_launcher.png b/src/pt/unionmangas/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index f70961fd0..000000000
Binary files a/src/pt/unionmangas/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/unionmangas/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/unionmangas/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index ff725b3a3..000000000
Binary files a/src/pt/unionmangas/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/unionmangas/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/unionmangas/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index e4f74dade..000000000
Binary files a/src/pt/unionmangas/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/unionmangas/res/web_hi_res_512.png b/src/pt/unionmangas/res/web_hi_res_512.png
deleted file mode 100644
index fe53ed3ad..000000000
Binary files a/src/pt/unionmangas/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/pt/unionmangas/src/eu/kanade/tachiyomi/extension/pt/unionmangas/UnionMangas.kt b/src/pt/unionmangas/src/eu/kanade/tachiyomi/extension/pt/unionmangas/UnionMangas.kt
deleted file mode 100644
index 7e4700463..000000000
--- a/src/pt/unionmangas/src/eu/kanade/tachiyomi/extension/pt/unionmangas/UnionMangas.kt
+++ /dev/null
@@ -1,278 +0,0 @@
-package eu.kanade.tachiyomi.extension.pt.unionmangas
-
-import com.github.salomonbrys.kotson.array
-import com.github.salomonbrys.kotson.nullObj
-import com.github.salomonbrys.kotson.obj
-import com.github.salomonbrys.kotson.string
-import com.google.gson.JsonElement
-import com.google.gson.JsonObject
-import com.google.gson.JsonParser
-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
-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.ParsedHttpSource
-import okhttp3.FormBody
-import okhttp3.Headers
-import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import org.jsoup.nodes.Document
-import org.jsoup.nodes.Element
-import java.text.ParseException
-import java.text.SimpleDateFormat
-import java.util.Locale
-import java.util.concurrent.TimeUnit
-
-class UnionMangas : ParsedHttpSource() {
-
- // Hardcode the id because the language wasn't specific.
- override val id: Long = 6931383302802153355
-
- override val name = "Union Mangás"
-
- override val baseUrl = "https://unionmangas.top"
-
- override val lang = "pt-BR"
-
- override val supportsLatest = true
-
- override val client: OkHttpClient = network.cloudflareClient.newBuilder()
- .connectTimeout(3, TimeUnit.MINUTES)
- .readTimeout(3, TimeUnit.MINUTES)
- .writeTimeout(3, TimeUnit.MINUTES)
- .addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
- .build()
-
- override fun headersBuilder(): Headers.Builder = Headers.Builder()
- .add("Accept", ACCEPT)
- .add("Accept-Language", ACCEPT_LANGUAGE)
- .add("Referer", "$baseUrl/home")
-
- override fun popularMangaRequest(page: Int): Request {
- val listPath = if (page == 1) "" else "/visualizacoes/${page - 1}"
- val newHeaders = headersBuilder()
- .set("Referer", "$baseUrl/lista-mangas$listPath")
- .build()
-
- val pageStr = if (page != 1) "/$page" else ""
- return GET("$baseUrl/lista-mangas/visualizacoes$pageStr", newHeaders)
- }
-
- override fun popularMangaParse(response: Response): MangasPage {
- val results = super.popularMangaParse(response)
-
- if (results.mangas.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return results
- }
-
- override fun popularMangaSelector(): String = "div.col-md-3.col-xs-6:has(img.img-thumbnail)"
-
- override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
- title = element.select("div[id^=bloco-tooltip] > b").first().text().withoutLanguage()
- thumbnail_url = element.select("a img").first()?.attr("src")
- setUrlWithoutDomain(element.select("a").last().attr("href"))
- }
-
- override fun popularMangaNextPageSelector() = ".pagination li:contains(Next)"
-
- override fun latestUpdatesRequest(page: Int): Request {
- val form = FormBody.Builder()
- .add("pagina", page.toString())
- .build()
-
- val newHeaders = headersBuilder()
- .add("Content-Type", form.contentType().toString())
- .add("Content-Length", form.contentLength().toString())
- .add("Origin", baseUrl)
- .add("X-Requested-With", "XMLHttpRequest")
- .set("Accept", "*/*")
- .build()
-
- return POST("$baseUrl/assets/noticias.php", newHeaders, form)
- }
-
- override fun latestUpdatesParse(response: Response): MangasPage {
- val results = super.latestUpdatesParse(response)
-
- if (results.mangas.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return results
- }
-
- override fun latestUpdatesSelector() = "div.row[style] div.col-md-12[style]"
-
- override fun latestUpdatesFromElement(element: Element): SManga = SManga.create().apply {
- val infoElement = element.select("a.link-titulo")
-
- title = infoElement.last().text().withoutLanguage()
- thumbnail_url = infoElement.first()?.select("img")?.attr("src")
- setUrlWithoutDomain(infoElement.last().attr("href"))
- }
-
- override fun latestUpdatesNextPageSelector() = "div#linha-botao-mais"
-
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
- if (query.startsWith(PREFIX_SLUG_SEARCH)) {
- val slug = query.removePrefix(PREFIX_SLUG_SEARCH)
- return GET("$baseUrl/pagina-manga/$slug", headers)
- }
-
- val newHeaders = headersBuilder()
- .set("Accept", ACCEPT_JSON)
- .add("X-Requested-With", "XMLHttpRequest")
- .build()
-
- val url = "$baseUrl/assets/busca.php".toHttpUrlOrNull()!!.newBuilder()
- .addQueryParameter("titulo", query)
-
- return GET(url.toString(), newHeaders)
- }
-
- override fun searchMangaParse(response: Response): MangasPage {
- val requestUrl = response.request.url.toString()
-
- if (requestUrl.contains("pagina-manga")) {
- val slug = requestUrl.substringAfter("pagina-manga/")
- val manga = mangaDetailsParse(response)
- .apply { url = "/pagina-manga/$slug" }
- return MangasPage(listOf(manga), false)
- }
-
- val result = response.asJson().nullObj
- ?: throw Exception(BLOCK_MESSAGE)
-
- val mangas = result["items"].array
- .map { searchMangaFromObject(it.obj) }
-
- return MangasPage(mangas, false)
- }
-
- private fun searchMangaFromObject(obj: JsonObject): SManga = SManga.create().apply {
- title = obj["titulo"].string.withoutLanguage()
- thumbnail_url = obj["imagem"].string
- setUrlWithoutDomain("$baseUrl/pagina-manga/${obj["url"].string}")
- }
-
- override fun mangaDetailsRequest(manga: SManga): Request {
- // Map the mangas that are already in library with the old URL to the new one.
- val newUrl = manga.url.replace("perfil-manga", "pagina-manga")
- return GET(baseUrl + newUrl, headers)
- }
-
- override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
- val infoElement = document.select("div.perfil-manga").firstOrNull()
- ?: throw Exception(BLOCK_MESSAGE)
- val rowInfo = infoElement.select("div.row:eq(2)").first()
-
- title = infoElement.select("h2").first().text().withoutLanguage()
- author = rowInfo.select("div.col-md-8:eq(4)").first().textWithoutLabel()
- artist = rowInfo.select("div.col-md-8:eq(5)").first().textWithoutLabel()
- genre = rowInfo.select("div.col-md-8:eq(3)").first().textWithoutLabel()
- status = rowInfo.select("div.col-md-8:eq(6)").first().text().toStatus()
- description = rowInfo.select("div.col-md-8:eq(8)").first().text()
- thumbnail_url = infoElement.select(".img-thumbnail").first().attr("src")
- }
-
- override fun chapterListParse(response: Response): List {
- val results = super.chapterListParse(response)
-
- if (results.isEmpty()) {
- throw Exception(BLOCK_MESSAGE)
- }
-
- return results
- }
-
- override fun chapterListSelector() = "div.row.capitulos"
-
- override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
- val firstColumn = element.select("div.col-md-6:eq(0)").first()!!
- val secondColumn = element.select("div.col-md-6:eq(1)").firstOrNull()
-
- name = firstColumn.select("a").first().text()
- scanlator = secondColumn?.select("a")?.joinToString { it.text() }
- date_upload = firstColumn.select("span").last()!!.text().toDate()
-
- // For some reason, setUrlWithoutDomain does not work when the url have spaces.
- val absoluteUrlFixed = firstColumn.select("a").first()
- .attr("href")
- .replace(" ", "%20")
- setUrlWithoutDomain(absoluteUrlFixed)
- }
-
- override fun pageListParse(document: Document): List {
- return document.select("img.img-responsive.img-manga")
- .filter { it.attr("src").contains("/leitor/") }
- .mapIndexed { i, element ->
- Page(i, document.location(), element.absUrl("src"))
- }
- }
-
- override fun imageUrlParse(document: Document) = ""
-
- override fun imageRequest(page: Page): Request {
- val newHeaders = headersBuilder()
- .set("Accept", ACCEPT_IMAGE)
- .set("Referer", page.url)
- .build()
-
- return GET(page.imageUrl!!, newHeaders)
- }
-
- override fun searchMangaSelector() = throw Exception("This method should not be called!")
-
- override fun searchMangaFromElement(element: Element): SManga = throw Exception("This method should not be called!")
-
- override fun searchMangaNextPageSelector() = throw Exception("This method should not be called!")
-
- private fun String.toDate(): Long {
- return try {
- DATE_FORMATTER.parse(this)?.time ?: 0L
- } catch (e: ParseException) {
- 0L
- }
- }
-
- private fun String.toStatus(): Int = when {
- contains("Ativo") -> SManga.ONGOING
- contains("Completo") -> SManga.COMPLETED
- else -> SManga.UNKNOWN
- }
-
- private fun String.withoutLanguage(): String =
- replace("(pt-br)", "", true).trim()
-
- private fun Element.textWithoutLabel(): String = text()!!.substringAfter(":").trim()
-
- private fun Response.asJson(): JsonElement = JsonParser.parseString(body!!.string())
-
- companion object {
- private const val ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9," +
- "image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
- private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
- private const val ACCEPT_JSON = "application/json, text/javascript, */*; q=0.01"
- private const val ACCEPT_LANGUAGE = "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6,gl;q=0.5"
- private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
- "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36"
-
- private const val BLOCK_MESSAGE = "O site está bloqueando o Tachiyomi. " +
- "Migre para outra fonte caso o problema persistir."
-
- private val DATE_FORMATTER by lazy {
- SimpleDateFormat("(dd/MM/yyyy)", Locale.ENGLISH)
- }
-
- const val PREFIX_SLUG_SEARCH = "slug:"
- }
-}
diff --git a/src/pt/unionmangas/src/eu/kanade/tachiyomi/extension/pt/unionmangas/UnionMangasUrlActivity.kt b/src/pt/unionmangas/src/eu/kanade/tachiyomi/extension/pt/unionmangas/UnionMangasUrlActivity.kt
deleted file mode 100644
index eebd580d3..000000000
--- a/src/pt/unionmangas/src/eu/kanade/tachiyomi/extension/pt/unionmangas/UnionMangasUrlActivity.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package eu.kanade.tachiyomi.extension.pt.unionmangas
-
-import android.app.Activity
-import android.content.ActivityNotFoundException
-import android.content.Intent
-import android.os.Bundle
-import android.util.Log
-import kotlin.system.exitProcess
-
-/**
- * Springboard that accepts https://unionleitor.top/perfil-manga/xxxxxx intents
- * and redirects them to the main Tachiyomi process.
- */
-class UnionMangasUrlActivity : Activity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- val pathSegments = intent?.data?.pathSegments
- if (pathSegments != null && pathSegments.size > 1) {
- val slug = pathSegments[1]
- val mainIntent = Intent().apply {
- action = "eu.kanade.tachiyomi.SEARCH"
- putExtra("query", "${UnionMangas.PREFIX_SLUG_SEARCH}$slug")
- putExtra("filter", packageName)
- }
-
- try {
- startActivity(mainIntent)
- } catch (e: ActivityNotFoundException) {
- Log.e("UnionMangasUrl", e.toString())
- }
- } else {
- Log.e("UnionMangasUrl", "could not parse uri from intent $intent")
- }
-
- finish()
- exitProcess(0)
- }
-}
diff --git a/src/pt/yesmangas/AndroidManifest.xml b/src/pt/yesmangas/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/pt/yesmangas/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/pt/yesmangas/build.gradle b/src/pt/yesmangas/build.gradle
deleted file mode 100644
index 69273f976..000000000
--- a/src/pt/yesmangas/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-
-ext {
- extName = 'YES Mangás'
- pkgNameSuffix = 'pt.yesmangas'
- extClass = '.YesMangas'
- extVersionCode = 7
- libVersion = '1.2'
-}
-
-dependencies {
- implementation project(':lib-ratelimit')
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/pt/yesmangas/res/mipmap-hdpi/ic_launcher.png b/src/pt/yesmangas/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 3b91c99e5..000000000
Binary files a/src/pt/yesmangas/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/yesmangas/res/mipmap-mdpi/ic_launcher.png b/src/pt/yesmangas/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 51afc3037..000000000
Binary files a/src/pt/yesmangas/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/yesmangas/res/mipmap-xhdpi/ic_launcher.png b/src/pt/yesmangas/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index f0662aa59..000000000
Binary files a/src/pt/yesmangas/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/yesmangas/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/yesmangas/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 7f3a529c6..000000000
Binary files a/src/pt/yesmangas/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/yesmangas/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/yesmangas/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index dc63f07bd..000000000
Binary files a/src/pt/yesmangas/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/yesmangas/res/web_hi_res_512.png b/src/pt/yesmangas/res/web_hi_res_512.png
deleted file mode 100644
index 9c518e509..000000000
Binary files a/src/pt/yesmangas/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/pt/yesmangas/src/eu/kanade/tachiyomi/extension/pt/yesmangas/YesMangas.kt b/src/pt/yesmangas/src/eu/kanade/tachiyomi/extension/pt/yesmangas/YesMangas.kt
deleted file mode 100644
index 101d351db..000000000
--- a/src/pt/yesmangas/src/eu/kanade/tachiyomi/extension/pt/yesmangas/YesMangas.kt
+++ /dev/null
@@ -1,146 +0,0 @@
-package eu.kanade.tachiyomi.extension.pt.yesmangas
-
-import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.source.model.FilterList
-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.ParsedHttpSource
-import okhttp3.Headers
-import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import org.jsoup.nodes.Document
-import org.jsoup.nodes.Element
-import org.jsoup.select.Elements
-import java.util.concurrent.TimeUnit
-
-class YesMangas : ParsedHttpSource() {
-
- // Hardcode the id because the language wasn't specific.
- override val id: Long = 7187189302580957274
-
- override val name = "YES Mangás"
-
- override val baseUrl = "https://yesmangas1.com"
-
- override val lang = "pt-BR"
-
- override val supportsLatest = true
-
- override val client: OkHttpClient = network.cloudflareClient.newBuilder()
- .addInterceptor(RateLimitInterceptor(1, 1, TimeUnit.SECONDS))
- .build()
-
- override fun headersBuilder(): Headers.Builder = Headers.Builder()
- .add("User-Agent", USER_AGENT)
- .add("Origin", baseUrl)
- .add("Referer", baseUrl)
-
- override fun popularMangaRequest(page: Int): Request = GET(baseUrl, headers)
-
- override fun popularMangaSelector(): String = "div#destaques div.three.columns a.img"
-
- override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
- title = element.attr("title").withoutLanguage()
- thumbnail_url = element.select("img").attr("data-path").toLargeUrl()
- url = element.attr("href")
- }
-
- override fun popularMangaNextPageSelector(): String? = null
-
- override fun latestUpdatesRequest(page: Int): Request = GET(baseUrl, headers)
-
- override fun latestUpdatesSelector(): String = "div#lancamentos table.u-full-width tbody tr td:eq(0) a"
-
- override fun latestUpdatesFromElement(element: Element): SManga = SManga.create().apply {
- title = element.attr("title").withoutLanguage()
- thumbnail_url = element.select("img").attr("data-path").toLargeUrl()
- setUrlWithoutDomain(element.attr("href"))
- }
-
- override fun latestUpdatesNextPageSelector(): String? = null
-
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
- val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
- .addQueryParameter("q", query)
-
- return GET(url.toString(), headers)
- }
-
- override fun searchMangaSelector(): String = "tbody#leituras tr td:eq(0) a"
-
- override fun searchMangaFromElement(element: Element): SManga = SManga.create().apply {
- title = element.attr("title").withoutLanguage()
- thumbnail_url = element.select("img").attr("data-path").toLargeUrl()
- setUrlWithoutDomain(element.attr("href"))
- }
-
- override fun searchMangaNextPageSelector(): String? = null
-
- override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
- val container = document.select("div#descricao").first()
-
- author = container.select("ul li:contains(Autor)").textWithoutLabel()
- artist = container.select("ul li:contains(Desenho)").textWithoutLabel()
- genre = container.select("ul li:contains(Categorias)").textWithoutLabel()
- status = container.select("ul li:contains(Status)").text().toStatus()
- description = container.select("article").text()
- .substringBefore("Relacionados")
- thumbnail_url = container.select("img").first()
- .attr("data-path")
- .toLargeUrl()
- }
-
- override fun chapterListSelector(): String = "div#capitulos a.button"
-
- override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
- name = element.attr("title").substringAfter(" - ")
- chapter_number = element.text().toFloatOrNull() ?: -1f
- setUrlWithoutDomain(element.attr("href"))
- }
-
- override fun pageListRequest(chapter: SChapter): Request {
- val newHeaders = headersBuilder()
- .set("Referer", baseUrl + chapter.url.substringBeforeLast("/"))
- .build()
-
- return GET(baseUrl + chapter.url, newHeaders)
- }
-
- override fun pageListParse(document: Document): List {
- return document.select("div.read-slideshow a img")
- .mapIndexed { i, el -> Page(i, document.location(), el.attr("src")) }
- }
-
- override fun imageUrlParse(document: Document): String = ""
-
- override fun imageRequest(page: Page): Request {
- val newHeaders = headersBuilder()
- .set("Referer", page.url)
- .build()
-
- return GET(page.imageUrl!!, newHeaders)
- }
-
- private fun String.withoutLanguage(): String = replace(LANG_REGEX, "")
-
- private fun String.toLargeUrl(): String = replace(IMAGE_REGEX, "_full.")
-
- private fun Elements.textWithoutLabel(): String = text()!!.substringAfter(":").trim()
-
- private fun String.toStatus() = when {
- contains("Completo") -> SManga.COMPLETED
- contains("Ativo") -> SManga.ONGOING
- else -> SManga.UNKNOWN
- }
-
- companion object {
- private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
- "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36"
-
- private val LANG_REGEX = "( )?\\((PT-)?BR\\)".toRegex()
- private val IMAGE_REGEX = "_(small|medium|xmedium|xlarge)\\.".toRegex()
- }
-}