diff --git a/src/id/oploverz/build.gradle b/src/id/oploverz/build.gradle index 978e7cdee..df492cc72 100644 --- a/src/id/oploverz/build.gradle +++ b/src/id/oploverz/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'Oploverz' pkgNameSuffix = 'id.oploverz' extClass = '.Oploverz' - extVersionCode = 16 + extVersionCode = 17 libVersion = '13' } diff --git a/src/id/oploverz/res/mipmap-hdpi/ic_launcher.png b/src/id/oploverz/res/mipmap-hdpi/ic_launcher.png index b9e963713..9639d6f3a 100644 Binary files a/src/id/oploverz/res/mipmap-hdpi/ic_launcher.png and b/src/id/oploverz/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/id/oploverz/res/mipmap-mdpi/ic_launcher.png b/src/id/oploverz/res/mipmap-mdpi/ic_launcher.png index edc11714e..456ed83ca 100644 Binary files a/src/id/oploverz/res/mipmap-mdpi/ic_launcher.png and b/src/id/oploverz/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/id/oploverz/res/mipmap-xhdpi/ic_launcher.png b/src/id/oploverz/res/mipmap-xhdpi/ic_launcher.png index f19e63901..461049d40 100644 Binary files a/src/id/oploverz/res/mipmap-xhdpi/ic_launcher.png and b/src/id/oploverz/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/id/oploverz/res/mipmap-xxhdpi/ic_launcher.png b/src/id/oploverz/res/mipmap-xxhdpi/ic_launcher.png index 7a3d08c3e..ec6b148e4 100644 Binary files a/src/id/oploverz/res/mipmap-xxhdpi/ic_launcher.png and b/src/id/oploverz/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/id/oploverz/res/mipmap-xxxhdpi/ic_launcher.png b/src/id/oploverz/res/mipmap-xxxhdpi/ic_launcher.png index fdc32d03f..7419537ee 100644 Binary files a/src/id/oploverz/res/mipmap-xxxhdpi/ic_launcher.png and b/src/id/oploverz/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/id/oploverz/res/web_hi_res_512.png b/src/id/oploverz/res/web_hi_res_512.png index 4d668b41b..f6e7473a0 100644 Binary files a/src/id/oploverz/res/web_hi_res_512.png and b/src/id/oploverz/res/web_hi_res_512.png differ diff --git a/src/id/oploverz/src/eu/kanade/tachiyomi/animeextension/id/oploverz/Oploverz.kt b/src/id/oploverz/src/eu/kanade/tachiyomi/animeextension/id/oploverz/Oploverz.kt index d5226a22c..ebaba9eb5 100644 --- a/src/id/oploverz/src/eu/kanade/tachiyomi/animeextension/id/oploverz/Oploverz.kt +++ b/src/id/oploverz/src/eu/kanade/tachiyomi/animeextension/id/oploverz/Oploverz.kt @@ -6,234 +6,230 @@ import androidx.preference.ListPreference import androidx.preference.PreferenceScreen 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.animesource.online.AnimeHttpSource import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.util.asJsoup +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.runBlocking +import okhttp3.FormBody import okhttp3.Request import okhttp3.Response +import org.json.JSONObject import org.jsoup.nodes.Document import org.jsoup.nodes.Element import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -import java.lang.Exception -import java.lang.RuntimeException -import java.lang.StringBuilder import java.text.SimpleDateFormat import java.util.Locale -class Oploverz : ConfigurableAnimeSource, ParsedAnimeHttpSource() { - override val baseUrl: String = "https://oploverz.fit" - override val lang: String = "id" +class Oploverz : ConfigurableAnimeSource, AnimeHttpSource() { override val name: String = "Oploverz" + override val baseUrl: String = "https://oploverz.red" + override val lang: String = "id" override val supportsLatest: Boolean = true private val preferences: SharedPreferences by lazy { Injekt.get().getSharedPreferences("source_$id", 0x0000) } - override fun animeDetailsParse(document: Document): SAnime { - val anime = SAnime.create() - val infox = document.select("div.bigcontent > div.infox") - val status = parseStatus(infox.select("div > div.info-content > div.spe > span:nth-child(1)").text().replace("Status: ", "")) - anime.title = infox.select("h1").text().replace("Judul: ", "") - anime.genre = infox.select("div > div.info-content > div.genxed > a").joinToString(", ") { it.text() } - anime.status = status - anime.artist = infox.select("div > div.info-content > div.spe > span:nth-child(2)").text() + // ============================== Popular =============================== - // Others - // Jap title - anime.author = when { - infox.select("div > span.alter").isNullOrEmpty() -> "Alternative = -" - else -> "Alternative = " + infox.select("div > span.alter").text() + override fun popularAnimeRequest(page: Int): Request = + GET("$baseUrl/anime-list/page/$page/?order=popular") + + override fun popularAnimeParse(response: Response): AnimesPage { + val doc = response.asJsoup() + val animes = doc.select("div.relat > article").map { + getAnimeFromAnimeElement(it) } - // Score - anime.description = "\n" + document.select("div.bigcontent > div.thumbook > div.rt > div.rating > strong").text() - // Total Episode - anime.description = anime.description + "\n" + document.select("div > div.info-content > div.spe > span:nth-child(7)").text() - // Synopsis - anime.description = anime.description + "\n\n\nSynopsis: \n" + document.select("div.bixbox.synp > div.entry-content > p").joinToString("\n\n") { it.text() } - return anime + return AnimesPage(animes, hasNextPage(doc)) } - private fun parseStatus(statusString: String): Int { - return when (statusString.toLowerCase(Locale.US)) { - "ongoing" -> SAnime.ONGOING + // =============================== Latest =============================== + + override fun latestUpdatesRequest(page: Int): Request = + GET("$baseUrl/anime-list/page/$page/?order=latest") + + override fun latestUpdatesParse(response: Response): AnimesPage { + val doc = response.asJsoup() + val animes = doc.select("div.relat > article").map { + getAnimeFromAnimeElement(it) + } + return AnimesPage(animes, hasNextPage(doc)) + } + + // =============================== Search =============================== + + override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = + GET("$baseUrl/page/$page/?s=$query") + + override fun searchAnimeParse(response: Response): AnimesPage { + val doc = response.asJsoup() + val animes = doc.select("main.site-main.relat > article").map { + getAnimeFromAnimeElement(it) + } + return AnimesPage(animes, hasNextPage(doc)) + } + + // =========================== Anime Details ============================ + + override fun animeDetailsParse(response: Response): SAnime { + val doc = response.asJsoup() + val detail = doc.selectFirst("div.infox > div.spe")!! + return SAnime.create().apply { + author = detail.getInfo("Studio") + status = parseStatus(doc.selectFirst("div.alternati > span:nth-child(2)")!!.text()) + title = doc.selectFirst("div.title > h1.entry-title")!!.text() + thumbnail_url = + doc.selectFirst("div.infoanime.widget_senction > div.thumb > img")!! + .attr("src") + description = + doc.select("div.entry-content.entry-content-single > p") + .joinToString("\n\n") { it.text() } + } + } + + // ============================== Episodes ============================== + + override fun episodeListParse(response: Response): List { + val doc = response.asJsoup() + return doc.select("div.lstepsiode.listeps > ul.scrolling > li").map { + val episode = it.selectFirst("span.eps > a")!! + SEpisode.create().apply { + setUrlWithoutDomain(episode.attr("href")) + episode_number = episode.text().trim().toFloatOrNull() ?: 1F + name = it.selectFirst("span.lchx > a")!!.text() + date_upload = it.selectFirst("span.date")!!.text().toDate() + } + } + } + + // ============================ Video Links ============================= + + override fun videoListParse(response: Response): List