diff --git a/src/pt/animesotaku/AndroidManifest.xml b/src/pt/animesotaku/AndroidManifest.xml deleted file mode 100644 index 344af03c..00000000 --- a/src/pt/animesotaku/AndroidManifest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/pt/animesotaku/build.gradle b/src/pt/animesotaku/build.gradle deleted file mode 100644 index 4031a00f..00000000 --- a/src/pt/animesotaku/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -ext { - extName = 'AnimesOtaku' - extClass = '.AnimesOtaku' - extVersionCode = 1 -} - -apply from: "$rootDir/common.gradle" - -dependencies { - implementation(project(":lib:blogger-extractor")) -} diff --git a/src/pt/animesotaku/res/mipmap-hdpi/ic_launcher.png b/src/pt/animesotaku/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 13f236fb..00000000 Binary files a/src/pt/animesotaku/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/animesotaku/res/mipmap-mdpi/ic_launcher.png b/src/pt/animesotaku/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 7ba8b02c..00000000 Binary files a/src/pt/animesotaku/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/animesotaku/res/mipmap-xhdpi/ic_launcher.png b/src/pt/animesotaku/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 71bed724..00000000 Binary files a/src/pt/animesotaku/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/animesotaku/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/animesotaku/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index acadcc41..00000000 Binary files a/src/pt/animesotaku/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/animesotaku/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/animesotaku/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index ef8f94e8..00000000 Binary files a/src/pt/animesotaku/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/animesotaku/src/eu/kanade/tachiyomi/animeextension/pt/animesotaku/AnimesOtaku.kt b/src/pt/animesotaku/src/eu/kanade/tachiyomi/animeextension/pt/animesotaku/AnimesOtaku.kt deleted file mode 100644 index 91c07458..00000000 --- a/src/pt/animesotaku/src/eu/kanade/tachiyomi/animeextension/pt/animesotaku/AnimesOtaku.kt +++ /dev/null @@ -1,244 +0,0 @@ -package eu.kanade.tachiyomi.animeextension.pt.animesotaku - -import android.util.Base64 -import eu.kanade.tachiyomi.animeextension.pt.animesotaku.dto.SearchRequestDto -import eu.kanade.tachiyomi.animeextension.pt.animesotaku.dto.SearchResponseDto -import eu.kanade.tachiyomi.animeextension.pt.animesotaku.dto.SingleDto -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.AnimeHttpSource -import eu.kanade.tachiyomi.lib.bloggerextractor.BloggerExtractor -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.parallelCatchingFlatMapBlocking -import eu.kanade.tachiyomi.util.parseAs -import kotlinx.serialization.encodeToString -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.injectLazy -import java.util.concurrent.TimeUnit - -class AnimesOtaku : AnimeHttpSource() { - - override val name = "Animes Otaku" - - override val baseUrl = "https://www.animesotaku.cc" - - override val lang = "pt" - - override val supportsLatest = true - - private val json: Json by injectLazy() - - override val client = network.client.newBuilder() - .connectTimeout(30, TimeUnit.SECONDS) - .writeTimeout(30, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .build() - - override fun headersBuilder() = super.headersBuilder() - .add("Referer", baseUrl) - - // ============================== Popular =============================== - override fun popularAnimeRequest(page: Int) = searchOrderBy("total_kiranime_views", page) - - override fun popularAnimeParse(response: Response): AnimesPage { - val results = response.parseAs() - val doc = Jsoup.parseBodyFragment(results.data) - val animes = doc.select("div.w-full:has(div.kira-anime)").map { - SAnime.create().apply { - thumbnail_url = it.selectFirst("img")?.attr("src") - with(it.selectFirst("h3 > a")!!) { - title = text().replace(" Assistir Online", "") - setUrlWithoutDomain(attr("href")) - } - } - } - - val page = response.request.url.queryParameter("page")?.toIntOrNull() ?: 1 - val hasNextPage = page < results.pages - return AnimesPage(animes, hasNextPage) - } - - // =============================== Latest =============================== - override fun latestUpdatesRequest(page: Int) = searchOrderBy("kiranime_anime_updated", page) - - override fun latestUpdatesParse(response: Response) = popularAnimeParse(response) - - // =============================== Search =============================== - override suspend fun getSearchAnime( - page: Int, - query: String, - filters: AnimeFilterList, - ): AnimesPage { - return if (query.startsWith(PREFIX_SEARCH)) { // URL intent handler - val id = query.removePrefix(PREFIX_SEARCH) - client.newCall(GET("$baseUrl/anime/$id")) - .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 getFilterList() = AnimesOtakuFilters.FILTER_LIST - - override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { - val params = AnimesOtakuFilters.getSearchParameters(filters) - val (meta, orderBy) = when (params.orderBy) { - "date", "title" -> Pair(null, params.orderBy) - else -> Pair(params.orderBy, "meta_value_num") - } - - val single = SingleDto( - paged = page, - key = meta, - order = params.order, - orderBy = orderBy, - season = params.season.ifEmpty { null }, - year = params.year.ifEmpty { null }, - ) - - val taxonomies = with(params) { - listOf(genres, status, producers, studios, types).filter { - it.terms.isNotEmpty() - } - } - - val requestDto = SearchRequestDto(single, query, query, taxonomies) - val requestData = json.encodeToString(requestDto) - return searchRequest(requestData, page) - } - - override fun searchAnimeParse(response: Response) = popularAnimeParse(response) - - private fun searchOrderBy(order: String, page: Int): Request { - val body = """ - { - "keyword": "", - "query": "", - "single": { - "paged": $page, - "orderby": "meta_value_num", - "meta_key": "$order", - "order": "desc" - }, - "tax": [] - } - """.trimIndent() - return searchRequest(body, page) - } - - private fun searchRequest(data: String, page: Int): Request { - val body = data.toRequestBody("application/json".toMediaType()) - return POST( - "$baseUrl/wp-json/kiranime/v1/anime/advancedsearch?_locale=user&page=$page", - headers, - body, - ) - } - - // =========================== Anime Details ============================ - override fun animeDetailsParse(response: Response) = SAnime.create().apply { - val document = response.asJsoup() - - setUrlWithoutDomain(document.location()) - thumbnail_url = document.selectFirst("div.anime-image img")?.attr("src") - title = - document.selectFirst("h1 span.show.anime")!!.text().replace(" Assistir Online", "") - genre = - document.select("span.leading-6 a[class~=border-opacity-30]").joinToString { it.text() } - description = document.selectFirst("div[data-synopsis]")?.text() - author = document.selectFirst("span.leading-6 a[href*=\"producer\"]:first-child")?.text() - artist = document.selectFirst("span.leading-6 a[href*=\"studio\"]:first-child")?.text() - } - - // ============================== Episodes ============================== - override fun episodeListParse(response: Response): List { - return getRealDoc(response.asJsoup()) - .select(episodeListSelector()) - .map(::episodeFromElement) - } - - fun episodeListSelector(): String = "div[data-current-slider=\"episode-list\"] a" - - fun episodeFromElement(element: Element) = SEpisode.create().apply { - setUrlWithoutDomain(element.attr("href")) - name = element.selectFirst("span.font-semibold")!!.text().trim() - episode_number = name.substringAfterLast(" ").toFloatOrNull() ?: 0F - } - - // ============================ Video Links ============================= - private val bloggerExtractor by lazy { BloggerExtractor(client) } - - override fun videoListParse(response: Response): List