From d28020e89a649247fc800806a6435a9b94fd4828 Mon Sep 17 00:00:00 2001 From: hexated Date: Fri, 25 Nov 2022 00:34:51 +0700 Subject: [PATCH] added tracker into AnimeIndo, AnimeSail, Gomunimeis --- AnimeIndoProvider/build.gradle.kts | 2 +- .../kotlin/com/hexated/AnimeIndoProvider.kt | 66 ++++++++++++++----- AnimeSailProvider/build.gradle.kts | 2 +- .../kotlin/com/hexated/AnimeSailProvider.kt | 64 ++++++++++++++---- Gomunimeis/build.gradle.kts | 2 +- .../src/main/kotlin/com/hexated/Gomunimeis.kt | 56 +++++++++++++--- 6 files changed, 147 insertions(+), 45 deletions(-) diff --git a/AnimeIndoProvider/build.gradle.kts b/AnimeIndoProvider/build.gradle.kts index 673b5736..ac276588 100644 --- a/AnimeIndoProvider/build.gradle.kts +++ b/AnimeIndoProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 3 +version = 4 cloudstream { diff --git a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt index 98a600ba..7ffbf926 100644 --- a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt +++ b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt @@ -1,7 +1,10 @@ package com.hexated +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.APIHolder.getCaptchaToken +import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId +import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor @@ -23,9 +26,11 @@ class AnimeIndoProvider : MainAPI() { ) companion object { + private const val jikanAPI = "https://api.jikan.moe/v4" + fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Special")) TvType.OVA - else if (t.contains("Movie")) TvType.AnimeMovie + return if (t.contains("OVA", true) || t.contains("Special")) TvType.OVA + else if (t.contains("Movie", true)) TvType.AnimeMovie else TvType.Anime } @@ -126,34 +131,37 @@ class AnimeIndoProvider : MainAPI() { } } - override suspend fun load(url: String): LoadResponse { + override suspend fun load(url: String): LoadResponse? { val document = request(url).document - val title = document.selectFirst("h1.entry-title")?.text().toString().trim() + val title = document.selectFirst("h1.entry-title")?.text()?.replace("Subtitle Indonesia", "") + ?.trim() ?: return null val poster = document.selectFirst("div.thumb > img[itemprop=image]")?.attr("src") val tags = document.select("div.genxed > a").map { it.text() } - val type = getType( - document.selectFirst("div.info-content > div.spe > span:nth-child(6)")?.ownText() - .toString() - ) - val year = Regex("\\d, ([0-9]*)").find( - document.select("div.info-content > div.spe > span:nth-child(9) > time").text() - )?.groupValues?.get(1)?.toIntOrNull() - val status = getStatus( - document.selectFirst("div.info-content > div.spe > span:nth-child(1)")!!.ownText() - .trim() - ) + val type = document.selectFirst("div.info-content > div.spe > span:contains(Type:)")?.ownText() + ?.trim()?.lowercase() ?: "tv" + val year = document.selectFirst("div.info-content > div.spe > span:contains(Released:)")?.ownText()?.let { + Regex("\\d,\\s([0-9]*)").find(it)?.groupValues?.get(1)?.toIntOrNull() + } + val status = getStatus(document.selectFirst("div.info-content > div.spe > span:nth-child(1)")!!.ownText().trim()) val description = document.select("div[itemprop=description] > p").text() + + val malId = app.get("${jikanAPI}/anime?q=$title&start_date=${year}&type=$type&limit=1") + .parsedSafe()?.data?.firstOrNull()?.mal_id + val anilistId = app.post( + "https://graphql.anilist.co/", data = mapOf( + "query" to "{Media(idMal:$malId,type:ANIME){id}}", + ) + ).parsedSafe()?.data?.media?.id val trailer = document.selectFirst("div.player-embed iframe")?.attr("src") val episodes = document.select("div.lstepsiode.listeps ul li").mapNotNull { val header = it.selectFirst("span.lchx > a") ?: return@mapNotNull null - val name = header.text().trim() val episode = header.text().trim().replace("Episode", "").trim().toIntOrNull() val link = fixUrl(header.attr("href")) - Episode(link, name = name, episode = episode) + Episode(link, episode = episode) }.reversed() - return newAnimeLoadResponse(title, url, type) { + return newAnimeLoadResponse(title, url, getType(type)) { engName = title posterUrl = poster this.year = year @@ -161,6 +169,8 @@ class AnimeIndoProvider : MainAPI() { showStatus = status plot = description this.tags = tags + addMalId(malId?.toIntOrNull()) + addAniListId(anilistId?.toIntOrNull()) addTrailer(trailer) } } @@ -188,5 +198,25 @@ class AnimeIndoProvider : MainAPI() { return true } + data class Data( + @JsonProperty("mal_id") val mal_id: String? = null, + ) + + data class JikanResponse( + @JsonProperty("data") val data: ArrayList? = arrayListOf(), + ) + + private data class IdAni( + @JsonProperty("id") val id: String? = null, + ) + + private data class MediaAni( + @JsonProperty("Media") val media: IdAni? = null, + ) + + private data class DataAni( + @JsonProperty("data") val data: MediaAni? = null, + ) + } \ No newline at end of file diff --git a/AnimeSailProvider/build.gradle.kts b/AnimeSailProvider/build.gradle.kts index 7fcac9c3..260c16b1 100644 --- a/AnimeSailProvider/build.gradle.kts +++ b/AnimeSailProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 2 +version = 3 cloudstream { diff --git a/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt b/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt index fc0e11ca..efb1e7f9 100644 --- a/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt +++ b/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt @@ -1,6 +1,9 @@ package com.hexated +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId +import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities @@ -23,9 +26,11 @@ class AnimeSailProvider : MainAPI() { ) companion object { + private const val jikanAPI = "https://api.jikan.moe/v4" + fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Special")) TvType.OVA - else if (t.contains("Movie")) TvType.AnimeMovie + return if (t.contains("OVA", true) || t.contains("Special")) TvType.OVA + else if (t.contains("Movie", true)) TvType.AnimeMovie else TvType.Anime } @@ -104,28 +109,38 @@ class AnimeSailProvider : MainAPI() { override suspend fun load(url: String): LoadResponse { val document = request(url).document - val title = document.selectFirst("h1.entry-title")?.text().toString().trim() - val type = getType( - document.select("tbody th:contains(Tipe)").next().text() - ) + val title = document.selectFirst("h1.entry-title")?.text().toString() + .replace("Subtitle Indonesia", "").trim() + val type = document.select("tbody th:contains(Tipe)").next().text().lowercase() + val year = document.select("tbody th:contains(Dirilis)").next().text().trim().toIntOrNull() + + val malId = app.get("${jikanAPI}/anime?q=$title&start_date=${year}&type=$type&limit=1") + .parsedSafe()?.data?.firstOrNull()?.mal_id + val anilistId = app.post( + "https://graphql.anilist.co/", data = mapOf( + "query" to "{Media(idMal:$malId,type:ANIME){id}}", + ) + ).parsedSafe()?.data?.media?.id + val episodes = document.select("ul.daftar > li").map { - val header = it.select("a").text().trim() - val name = - Regex("(Episode\\s?[0-9]+)").find(header)?.groupValues?.getOrNull(0) ?: header + val episode = Regex("Episode\\s?([0-9]+)").find( + it.select("a").text().trim() + )?.groupValues?.getOrNull(0) val link = fixUrl(it.select("a").attr("href")) - Episode(link, name = name) + Episode(link, episode = episode?.toIntOrNull()) }.reversed() - return newAnimeLoadResponse(title, url, type) { + return newAnimeLoadResponse(title, url, getType(type)) { posterUrl = document.selectFirst("div.entry-content > img")?.attr("src") - this.year = - document.select("tbody th:contains(Dirilis)").next().text().trim().toIntOrNull() + this.year = year addEpisodes(DubStatus.Subbed, episodes) showStatus = getStatus(document.select("tbody th:contains(Status)").next().text().trim()) plot = document.selectFirst("div.entry-content > p")?.text() this.tags = document.select("tbody th:contains(Genre)").next().select("a").map { it.text() } + addMalId(malId?.toIntOrNull()) + addAniListId(anilistId?.toIntOrNull()) } } @@ -172,7 +187,9 @@ class AnimeSailProvider : MainAPI() { // iframe.startsWith("$mainUrl/utils/player/fichan/") -> "" // iframe.startsWith("$mainUrl/utils/player/blogger/") -> "" iframe.startsWith("https://aghanim.xyz/tools/redirect/") -> { - val link = "https://rasa-cintaku-semakin-berantai.xyz/v/${iframe.substringAfter("id=").substringBefore("&token")}" + val link = "https://rasa-cintaku-semakin-berantai.xyz/v/${ + iframe.substringAfter("id=").substringBefore("&token") + }" loadExtractor(link, mainUrl, subtitleCallback, callback) } iframe.startsWith("$mainUrl/utils/player/framezilla/") || iframe.startsWith("https://uservideo.xyz") -> { @@ -191,5 +208,24 @@ class AnimeSailProvider : MainAPI() { return true } + data class Data( + @JsonProperty("mal_id") val mal_id: String? = null, + ) + + data class JikanResponse( + @JsonProperty("data") val data: ArrayList? = arrayListOf(), + ) + + private data class IdAni( + @JsonProperty("id") val id: String? = null, + ) + + private data class MediaAni( + @JsonProperty("Media") val media: IdAni? = null, + ) + + private data class DataAni( + @JsonProperty("data") val data: MediaAni? = null, + ) } \ No newline at end of file diff --git a/Gomunimeis/build.gradle.kts b/Gomunimeis/build.gradle.kts index b329c01b..9db143ab 100644 --- a/Gomunimeis/build.gradle.kts +++ b/Gomunimeis/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { diff --git a/Gomunimeis/src/main/kotlin/com/hexated/Gomunimeis.kt b/Gomunimeis/src/main/kotlin/com/hexated/Gomunimeis.kt index e9312963..03834fb5 100644 --- a/Gomunimeis/src/main/kotlin/com/hexated/Gomunimeis.kt +++ b/Gomunimeis/src/main/kotlin/com/hexated/Gomunimeis.kt @@ -2,6 +2,8 @@ package com.hexated import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId +import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.utils.* import java.util.ArrayList @@ -21,7 +23,7 @@ class Gomunimeis : MainAPI() { ) companion object { - + private const val jikanAPI = "https://api.jikan.moe/v4" private const val mainImageUrl = "https://upload.anoboy.live" fun getType(t: String): TvType { @@ -92,26 +94,38 @@ class Gomunimeis : MainAPI() { val title = document.selectFirst(".entry-title")?.text().toString() val poster = document.selectFirst(".thumbposter > img")?.attr("src") val tags = document.select(".genxed > a").map { it.text() } - val type = getType(document.selectFirst("div.info-content .spe span:last-child")?.ownText().toString()) + val type = document.selectFirst("div.info-content .spe span:last-child")?.ownText()?.lowercase() ?: "tv" + val year = Regex("\\d, ([0-9]*)").find( document.selectFirst("div.info-content .spe span.split")?.ownText().toString() )?.groupValues?.get(1)?.toIntOrNull() val status = getStatus(document.selectFirst(".spe > span")!!.ownText()) val description = document.select("div[itemprop = description] > p").text() + val malId = app.get("${jikanAPI}/anime?q=$title&start_date=${year}&type=$type&limit=1") + .parsedSafe()?.data?.firstOrNull()?.mal_id + val anilistId = app.post( + "https://graphql.anilist.co/", data = mapOf( + "query" to "{Media(idMal:$malId,type:ANIME){id}}", + ) + ).parsedSafe()?.data?.media?.id + val episodes = document.select(".eplister > ul > li").map { - val header = it.select(".epl-title").text() - val name = Regex("(Episode\\s?[0-9]+)").find(header)?.groupValues?.getOrNull(0) ?: header + val episode = Regex("Episode\\s?([0-9]+)").find( + it.select(".epl-title").text() + )?.groupValues?.getOrNull(0) val link = it.select("a").attr("href") - Episode(link, name) + Episode(link, episode = episode?.toIntOrNull()) }.reversed() - return newAnimeLoadResponse(title, url, type) { + return newAnimeLoadResponse(title, url, getType(type)) { engName = title posterUrl = poster this.year = year addEpisodes(DubStatus.Subbed, episodes) showStatus = status + addMalId(malId?.toIntOrNull()) + addAniListId(anilistId?.toIntOrNull()) plot = description this.tags = tags } @@ -126,11 +140,13 @@ class Gomunimeis : MainAPI() { val document = app.get(data).document - document.select("div.player-container iframe").attr("src").substringAfter("html#").let { id -> - app.get("https://gomunimes.com/stream?id=$id").parsedSafe()?.server?.streamsb?.link?.let { link -> - loadExtractor(link, "https://vidgomunime.xyz/", subtitleCallback, callback) + document.select("div.player-container iframe").attr("src").substringAfter("html#") + .let { id -> + app.get("https://gomunimes.com/stream?id=$id") + .parsedSafe()?.server?.streamsb?.link?.let { link -> + loadExtractor(link, "https://vidgomunime.xyz/", subtitleCallback, callback) + } } - } return true } @@ -159,4 +175,24 @@ class Gomunimeis : MainAPI() { @JsonProperty("salt") val salt: String?, ) + data class Data( + @JsonProperty("mal_id") val mal_id: String? = null, + ) + + data class JikanResponse( + @JsonProperty("data") val data: ArrayList? = arrayListOf(), + ) + + private data class IdAni( + @JsonProperty("id") val id: String? = null, + ) + + private data class MediaAni( + @JsonProperty("Media") val media: IdAni? = null, + ) + + private data class DataAni( + @JsonProperty("data") val data: MediaAni? = null, + ) + } \ No newline at end of file