diff --git a/src/pt/animeszone/AndroidManifest.xml b/src/pt/animeszone/AndroidManifest.xml
deleted file mode 100644
index bc031e78..00000000
--- a/src/pt/animeszone/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/pt/animeszone/build.gradle b/src/pt/animeszone/build.gradle
deleted file mode 100644
index 6b089449..00000000
--- a/src/pt/animeszone/build.gradle
+++ /dev/null
@@ -1,12 +0,0 @@
-ext {
- extName = 'AnimesZone'
- extClass = '.AnimesZone'
- extVersionCode = 8
- isNsfw = true
-}
-
-apply from: "$rootDir/common.gradle"
-
-dependencies {
- implementation(project(':lib:dood-extractor'))
-}
diff --git a/src/pt/animeszone/res/mipmap-hdpi/ic_launcher.png b/src/pt/animeszone/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 2d1732e1..00000000
Binary files a/src/pt/animeszone/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/animeszone/res/mipmap-mdpi/ic_launcher.png b/src/pt/animeszone/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 0fb7c62e..00000000
Binary files a/src/pt/animeszone/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/animeszone/res/mipmap-xhdpi/ic_launcher.png b/src/pt/animeszone/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index be1ee581..00000000
Binary files a/src/pt/animeszone/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/animeszone/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/animeszone/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 489695ae..00000000
Binary files a/src/pt/animeszone/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/animeszone/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/animeszone/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 39fb6769..00000000
Binary files a/src/pt/animeszone/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/pt/animeszone/res/web_hi_res_512.png b/src/pt/animeszone/res/web_hi_res_512.png
deleted file mode 100644
index 07d80ae4..00000000
Binary files a/src/pt/animeszone/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/pt/animeszone/src/eu/kanade/tachiyomi/animeextension/pt/animeszone/AZUrlActivity.kt b/src/pt/animeszone/src/eu/kanade/tachiyomi/animeextension/pt/animeszone/AZUrlActivity.kt
deleted file mode 100644
index e701aadf..00000000
--- a/src/pt/animeszone/src/eu/kanade/tachiyomi/animeextension/pt/animeszone/AZUrlActivity.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package eu.kanade.tachiyomi.animeextension.pt.animeszone
-
-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://animeszone.net// intents
- * and redirects them to the main Aniyomi process.
- */
-class AZUrlActivity : Activity() {
-
- private val tag = javaClass.simpleName
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- val pathSegments = intent?.data?.pathSegments
- if (pathSegments != null && pathSegments.size > 1) {
- val searchQuery = "${pathSegments[0]}/${pathSegments[1]}"
-
- val mainIntent = Intent().apply {
- action = "eu.kanade.tachiyomi.ANIMESEARCH"
- putExtra("query", "${AnimesZone.PREFIX_SEARCH}$searchQuery")
- putExtra("filter", packageName)
- }
-
- try {
- startActivity(mainIntent)
- } catch (e: ActivityNotFoundException) {
- Log.e(tag, e.toString())
- }
- } else {
- Log.e(tag, "could not parse uri from intent $intent")
- }
-
- finish()
- exitProcess(0)
- }
-}
diff --git a/src/pt/animeszone/src/eu/kanade/tachiyomi/animeextension/pt/animeszone/AnimesZone.kt b/src/pt/animeszone/src/eu/kanade/tachiyomi/animeextension/pt/animeszone/AnimesZone.kt
deleted file mode 100644
index 04f40496..00000000
--- a/src/pt/animeszone/src/eu/kanade/tachiyomi/animeextension/pt/animeszone/AnimesZone.kt
+++ /dev/null
@@ -1,439 +0,0 @@
-package eu.kanade.tachiyomi.animeextension.pt.animeszone
-
-import android.app.Application
-import androidx.preference.ListPreference
-import androidx.preference.PreferenceScreen
-import app.cash.quickjs.QuickJs
-import eu.kanade.tachiyomi.animeextension.pt.animeszone.extractors.BloggerJWPlayerExtractor
-import eu.kanade.tachiyomi.animeextension.pt.animeszone.extractors.PlaylistExtractor
-import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
-import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
-import eu.kanade.tachiyomi.animesource.model.AnimesPage
-import eu.kanade.tachiyomi.animesource.model.SAnime
-import eu.kanade.tachiyomi.animesource.model.SEpisode
-import eu.kanade.tachiyomi.animesource.model.Video
-import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
-import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.network.POST
-import eu.kanade.tachiyomi.network.awaitSuccess
-import eu.kanade.tachiyomi.util.asJsoup
-import eu.kanade.tachiyomi.util.parseAs
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.json.Json
-import okhttp3.MediaType.Companion.toMediaType
-import okhttp3.Request
-import okhttp3.RequestBody.Companion.toRequestBody
-import okhttp3.Response
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Document
-import org.jsoup.nodes.Element
-import uy.kohesive.injekt.Injekt
-import uy.kohesive.injekt.api.get
-import uy.kohesive.injekt.injectLazy
-
-class AnimesZone : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
-
- override val name = "AnimesZone"
-
- override val baseUrl = "https://animeszone.net"
-
- override val lang = "pt-BR"
-
- override val supportsLatest = true
-
- override fun headersBuilder() = super.headersBuilder()
- .add("Referer", "$baseUrl/")
- .add("Origin", baseUrl)
-
- private val json: Json by injectLazy()
-
- private val preferences by lazy {
- Injekt.get().getSharedPreferences("source_$id", 0x0000)
- }
-
- // ============================== Popular ===============================
- override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/tendencia/")
-
- override fun popularAnimeSelector(): String = "div.items > div.seriesList"
-
- override fun popularAnimeNextPageSelector(): String? = null
-
- override fun popularAnimeFromElement(element: Element) = SAnime.create().apply {
- setUrlWithoutDomain(element.selectFirst("a[href]")!!.attr("abs:href"))
- thumbnail_url = element.selectFirst("div.cover-image")?.run {
- attr("style").substringAfter("url('").substringBefore("'")
- }
- title = element.selectFirst("span.series-title")!!.text()
- }
-
- // =============================== Latest ===============================
- override fun latestUpdatesRequest(page: Int): Request {
- return if (page == 1) {
- GET("$baseUrl/animes-legendados/")
- } else {
- GET("$baseUrl/animes-legendados/page/$page/")
- }
- }
-
- override fun latestUpdatesSelector(): String = "main#list-animes ul.post-lst > li"
-
- override fun latestUpdatesNextPageSelector(): String = "div.paginadorplay > a.active + a"
-
- override fun latestUpdatesFromElement(element: Element) = SAnime.create().apply {
- setUrlWithoutDomain(element.selectFirst("div.aniItem > a[href]")!!.attr("abs:href"))
- thumbnail_url = element.selectFirst("div.aniItemImg img[src]")?.attr("abs:src")
- title = element.selectFirst("h2.aniTitulo")!!.text()
- }
-
- // =============================== Search ===============================
- override suspend fun getSearchAnime(page: Int, query: String, filters: AnimeFilterList): AnimesPage {
- return if (query.startsWith(PREFIX_SEARCH)) {
- val path = query.removePrefix(PREFIX_SEARCH)
- client.newCall(GET("$baseUrl/$path"))
- .awaitSuccess()
- .use(::searchAnimeByIdParse)
- } else {
- super.getSearchAnime(page, query, filters)
- }
- }
-
- private fun searchAnimeByIdParse(response: Response): AnimesPage {
- val details = animeDetailsParse(response).apply {
- setUrlWithoutDomain(response.request.url.toString())
- initialized = true
- }
-
- return AnimesPage(listOf(details), false)
- }
-
- override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
- val params = AnimesZoneFilters.getSearchParameters(filters)
-
- val cleanQuery = query.replace(" ", "%20")
- val queryQuery = if (query.isBlank()) {
- ""
- } else {
- "&_pesquisa=$cleanQuery"
- }
- val url = "$baseUrl/?s=${params.genre}${params.year}${params.version}${params.studio}${params.type}${params.adult}$queryQuery"
-
- val httpParams = url.substringAfter("$baseUrl/?").split("&").joinToString(",") {
- val (key, value) = it.split("=", limit = 2)
- "\"$key\":\"$value\""
- }
- val softRefresh = if (page == 1) 0 else 1
- val jsonBody = """
- {
- "action":"facetwp_refresh",
- "data":{
- "facets":{
- "generos":[
- ${queryToJsonList(params.genre)}
- ],
- "versao":[
- ${queryToJsonList(params.year)}
- ],
- "tipo":[
- ${queryToJsonList(params.version)}
- ],
- "estudio":[
- ${queryToJsonList(params.studio)}
- ],
- "tipototal":[
- ${queryToJsonList(params.type)}
- ],
- "adulto":[
- ${queryToJsonList(params.adult)}
- ],
- "pesquisa":"$query",
- "paginar":[
-
- ]
- },
- "frozen_facets":{
-
- },
- "http_params":{
- "get":{
- $httpParams
- },
- "uri":"",
- "url_vars":[
-
- ]
- },
- "template":"wp",
- "extras":{
- "sort":"default"
- },
- "soft_refresh":$softRefresh,
- "is_bfcache":1,
- "first_load":0,
- "paged":$page
- }
- }
- """.trimIndent().toRequestBody("application/json".toMediaType())
-
- return POST(url, headers, jsonBody)
- }
-
- override fun searchAnimeParse(response: Response): AnimesPage {
- val parsed = response.parseAs()
-
- val document = Jsoup.parse(parsed.template)
-
- val animes = document.select(searchAnimeSelector()).map(::searchAnimeFromElement)
-
- val hasNextPage = parsed.settings.pager.run { page < total_pages }
-
- return AnimesPage(animes, hasNextPage)
- }
-
- override fun searchAnimeSelector(): String = "div.aniItem"
-
- override fun searchAnimeNextPageSelector(): String? = null
-
- override fun searchAnimeFromElement(element: Element) = SAnime.create().apply {
- setUrlWithoutDomain(element.selectFirst("a[href]")!!.attr("href"))
- thumbnail_url = element.selectFirst("img[src]")?.attr("abs:src")
- title = element.selectFirst("div.aniInfos")?.text() ?: "Anime"
- }
-
- // ============================== FILTERS ===============================
- override fun getFilterList(): AnimeFilterList = AnimesZoneFilters.FILTER_LIST
-
- // =========================== Anime Details ============================
- override fun animeDetailsParse(document: Document) = SAnime.create().apply {
- title = document.selectFirst("div.container > div div.bottom-div > h4")?.ownText()
- ?: document.selectFirst("div#info > h1")?.text()
- ?: "Anime"
- thumbnail_url = document.selectFirst("div.container > div > img[src]")?.attr("abs:src")
- description = document.selectFirst("section#sinopse p:matches(.)")?.text()
- ?: document.selectFirst("div.content.right > dialog > p:matches(.)")?.text()
- genre = document.select("div.card-body table > tbody > tr:has(>td:contains(Genres)) td > a").joinToString { it.text() }
- }
-
- // ============================== Episodes ==============================
- override fun episodeListParse(response: Response): List {
- val document = response.asJsoup()
-
- val singleVideo = document.selectFirst("div.anime__video__player")
-
- // First check if single episode
- return if (singleVideo != null) {
- SEpisode.create().apply {
- name = document.selectFirst("div#info h1")?.text() ?: "Episódio"
- episode_number = 1F
- setUrlWithoutDomain(document.location())
- }.let(::listOf)
- } else {
- buildList {
- document.select(episodeListSelector()).forEach { ep ->
- val name = ep.selectFirst("h2.aniTitulo")?.text()?.trim()
- // Check if it's multi-season
- var nextPageUrl = when {
- name != null && name.startsWith("temporada ", true) -> ep.selectFirst("a[href]")!!.attr("href")
- else -> {
- add(episodeFromElement(ep, size + 1))
- document.nextPageUrl()
- }
- }
-
- while (nextPageUrl != null) {
- val seasonDocument = client.newCall(GET(nextPageUrl)).execute()
- .asJsoup()
-
- seasonDocument.select(episodeListSelector()).forEach { seasonEp ->
- add(episodeFromElement(seasonEp, size + 1, name))
- }
-
- nextPageUrl = seasonDocument.nextPageUrl()
- }
- }
-
- reverse()
- }
- }
- }
-
- private fun Document.nextPageUrl() = selectFirst("div.paginadorplay > a:contains(Próxima Pagina)")?.absUrl("href")
-
- override fun episodeListSelector(): String = "main.site-main ul.post-lst > li"
-
- private fun episodeFromElement(element: Element, counter: Int, info: String? = null): SEpisode {
- val epTitle = element.selectFirst("div.title")?.text() ?: element.text()
- val epNumber = element.selectFirst("span.epiTipo")
-
- return SEpisode.create().apply {
- name = "Ep. ${epNumber?.text()?.trim() ?: counter} - ${epTitle.replace(EPISODE_REGEX, "")}"
- .replace(" - - ", " - ")
- episode_number = epNumber?.run {
- text().trim().toFloatOrNull()
- } ?: counter.toFloat()
- scanlator = info
- setUrlWithoutDomain(element.selectFirst("article > a")!!.attr("href"))
- }
- }
-
- override fun episodeFromElement(element: Element): SEpisode = throw UnsupportedOperationException()
-
- // ============================ Video Links =============================
- override fun videoListParse(response: Response): List