diff --git a/Anichi/build.gradle.kts b/Anichi/build.gradle.kts
deleted file mode 100644
index 643809b0..00000000
--- a/Anichi/build.gradle.kts
+++ /dev/null
@@ -1,42 +0,0 @@
-import org.jetbrains.kotlin.konan.properties.Properties
-
-// use an integer for version numbers
-version = 9
-
-android {
- defaultConfig {
- val properties = Properties()
- properties.load(project.rootProject.file("local.properties").inputStream())
-
- buildConfigField("String", "ANICHI_API", "\"${properties.getProperty("ANICHI_API")}\"")
- buildConfigField("String", "ANICHI_SERVER", "\"${properties.getProperty("ANICHI_SERVER")}\"")
- buildConfigField("String", "ANICHI_ENDPOINT", "\"${properties.getProperty("ANICHI_ENDPOINT")}\"")
- buildConfigField("String", "ANICHI_APP", "\"${properties.getProperty("ANICHI_APP")}\"")
-
-
- }
-}
-
-cloudstream {
- language = "en"
- // All of these properties are optional, you can safely remove them
-
- // description = "Lorem Ipsum"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 1 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "Anime",
- "OVA",
- )
-
- iconUrl = "https://media.discordapp.net/attachments/1059306855865782282/1123970193274712096/Anichi.png"
-}
\ No newline at end of file
diff --git a/Anichi/src/main/AndroidManifest.xml b/Anichi/src/main/AndroidManifest.xml
deleted file mode 100644
index 874740e3..00000000
--- a/Anichi/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Anichi/src/main/kotlin/com/hexated/Anichi.kt b/Anichi/src/main/kotlin/com/hexated/Anichi.kt
deleted file mode 100644
index bbad3ae7..00000000
--- a/Anichi/src/main/kotlin/com/hexated/Anichi.kt
+++ /dev/null
@@ -1,263 +0,0 @@
-package com.hexated
-
-import com.hexated.AnichiExtractors.invokeExternalSources
-import com.hexated.AnichiExtractors.invokeInternalSources
-import com.lagradost.cloudstream3.*
-import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
-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.syncproviders.SyncIdName
-import com.lagradost.cloudstream3.utils.*
-import com.lagradost.cloudstream3.utils.AppUtils.parseJson
-import com.lagradost.nicehttp.RequestBodyTypes
-import okhttp3.MediaType.Companion.toMediaTypeOrNull
-import okhttp3.RequestBody.Companion.toRequestBody
-
-open class Anichi : MainAPI() {
- override var name = "Anichi"
- override val instantLinkLoading = true
- override val hasQuickSearch = false
- override val hasMainPage = true
-
- private fun getStatus(t: String): ShowStatus {
- return when (t) {
- "Finished" -> ShowStatus.Completed
- "Releasing" -> ShowStatus.Ongoing
- else -> ShowStatus.Completed
- }
- }
-
- override val supportedSyncNames = setOf(SyncIdName.Anilist, SyncIdName.MyAnimeList)
- override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie)
-
- private val popularTitle = "Popular"
- private val animeRecentTitle = "Latest Anime"
- private val donghuaRecentTitle = "Latest Donghua"
- private val movieTitle = "Movie"
-
- override val mainPage = mainPageOf(
- """$apiUrl?variables={"search":{"sortBy":"Latest_Update","allowAdult":${settingsForProvider.enableAdult},"allowUnknown":false},"limit":26,"page":%d,"translationType":"sub","countryOrigin":"JP"}&extensions={"persistedQuery":{"version":1,"sha256Hash":"$mainHash"}}""" to animeRecentTitle,
- """$apiUrl?variables={"search":{"sortBy":"Latest_Update","allowAdult":${settingsForProvider.enableAdult},"allowUnknown":false},"limit":26,"page":%d,"translationType":"sub","countryOrigin":"CN"}&extensions={"persistedQuery":{"version":1,"sha256Hash":"$mainHash"}}""" to donghuaRecentTitle,
- """$apiUrl?variables={"type":"anime","size":30,"dateRange":1,"page":%d,"allowAdult":${settingsForProvider.enableAdult},"allowUnknown":false}&extensions={"persistedQuery":{"version":1,"sha256Hash":"$popularHash"}}""" to popularTitle,
- """$apiUrl?variables={"search":{"slug":"movie-anime","format":"anime","tagType":"upcoming","name":"Trending Movies"}}&extensions={"persistedQuery":{"version":1,"sha256Hash":"$slugHash"}}""" to movieTitle
- )
-
- override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
-
- val url = request.data.format(page)
- val res = app.get(url, headers = headers).parsedSafe()?.data
- val query = res?.shows ?: res?.queryPopular ?: res?.queryListForTag
- val card = if(request.name == popularTitle) query?.recommendations?.map { it.anyCard } else query?.edges
- val home = card?.filter {
- // filtering in case there is an anime with 0 episodes available on the site.
- !(it?.availableEpisodes?.raw == 0 && it.availableEpisodes.sub == 0 && it.availableEpisodes.dub == 0)
- }?.mapNotNull { media ->
- media?.toSearchResponse()
- } ?: emptyList()
- return newHomePageResponse(
- list = HomePageList(
- name = request.name,
- list = home,
- ),
- hasNext = request.name != movieTitle
- )
- }
-
- private fun Edges.toSearchResponse(): AnimeSearchResponse? {
-
- return newAnimeSearchResponse(
- name ?: englishName ?: nativeName ?: "",
- Id ?: return null,
- fix = false
- ) {
- this.posterUrl = thumbnail
- this.year = airedStart?.year
- this.otherName = englishName
- addDub(availableEpisodes?.dub)
- addSub(availableEpisodes?.sub)
- }
- }
-
- override suspend fun search(query: String): List? {
-
- val link =
- """$apiUrl?variables={"search":{"allowAdult":false,"allowUnknown":false,"query":"$query"},"limit":26,"page":1,"translationType":"sub","countryOrigin":"ALL"}&extensions={"persistedQuery":{"version":1,"sha256Hash":"$mainHash"}}"""
- val res = app.get(
- link,
- headers = headers
- ).text.takeUnless { it.contains("PERSISTED_QUERY_NOT_FOUND") }
- // Retries
- ?: app.get(
- link,
- headers = headers
- ).text.takeUnless { it.contains("PERSISTED_QUERY_NOT_FOUND") }
- ?: return emptyList()
-
- val response = parseJson(res)
-
- val results = response.data?.shows?.edges?.filter {
- // filtering in case there is an anime with 0 episodes available on the site.
- !(it.availableEpisodes?.raw == 0 && it.availableEpisodes.sub == 0 && it.availableEpisodes.dub == 0)
- }
-
- return results?.map {
- newAnimeSearchResponse(it.name ?: "", "${it.Id}", fix = false) {
- this.posterUrl = it.thumbnail
- this.year = it.airedStart?.year
- this.otherName = it.englishName
- addDub(it.availableEpisodes?.dub)
- addSub(it.availableEpisodes?.sub)
- }
- }
- }
-
- override suspend fun getLoadUrl(name: SyncIdName, id: String): String? {
- val syncId = id.split("/").last()
- val malId = if (name == SyncIdName.MyAnimeList) {
- syncId
- } else {
- aniToMal(syncId)
- }
-
- val media = app.get("$jikanApi/anime/$malId").parsedSafe()?.data
- val link =
- """$apiUrl?variables={"search":{"allowAdult":false,"allowUnknown":false,"query":"${media?.title}"},"limit":26,"page":1,"translationType":"sub","countryOrigin":"ALL"}&extensions={"persistedQuery":{"version":1,"sha256Hash":"$mainHash"}}"""
- val res = app.get(
- link,
- headers = headers
- ).parsedSafe()?.data?.shows?.edges
- return res?.find {
- (it.name.equals(media?.title, true) || it.englishName.equals(
- media?.title_english,
- true
- ) || it.nativeName.equals(media?.title_japanese, true)) && it.airedStart?.year == media?.year
- }?.Id
- }
-
- override suspend fun load(url: String): LoadResponse? {
-
- val id = url.substringAfterLast("/")
- // lazy to format
- val body = """
- {
- "query": " query(\n ${'$'}_id: String!\n ) {\n show(\n _id: ${'$'}_id\n ) {\n _id\n name\n description\n thumbnail\n thumbnails\n lastEpisodeInfo\n lastEpisodeDate \n type\n genres\n score\n status\n season\n altNames \n averageScore\n rating\n episodeCount\n episodeDuration\n broadcastInterval\n banner\n airedEnd\n airedStart \n studios\n characters\n availableEpisodesDetail\n availableEpisodes\n prevideos\n nameOnlyString\n relatedShows\n relatedMangas\n musics\n isAdult\n \n tags\n countryOfOrigin\n\n pageStatus{\n _id\n notes\n pageId\n showId\n \n # ranks:[Object]\n views\n likesCount\n commentCount\n dislikesCount\n reviewCount\n userScoreCount\n userScoreTotalValue\n userScoreAverValue\n viewers{\n firstViewers{\n viewCount\n lastWatchedDate\n user{\n _id\n displayName\n picture\n # description\n hideMe\n # createdAt\n # badges\n brief\n }\n \n }\n recViewers{\n viewCount\n lastWatchedDate\n user{\n _id\n displayName\n picture\n # description\n hideMe\n # createdAt\n # badges\n brief\n }\n \n }\n }\n\n }\n }\n }",
- "extensions": "{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"$detailHash\"}}",
- "variables": "{\"_id\":\"$id\"}"
- }
- """.trimIndent().trim().toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull())
-
- val res = app.post(apiUrl, requestBody = body, headers = headers)
- val showData = res.parsedSafe()?.data?.show ?: return null
-
- val title = showData.name
- val description = showData.description
- val poster = showData.thumbnail
-
- val trackers = getTracker(
- title,
- showData.altNames?.firstOrNull(),
- showData.airedStart?.year,
- showData.season?.quarter,
- showData.type
- )
-
- val episodes = showData.availableEpisodesDetail.let {
- if (it == null) return@let Pair(null, null)
- if (showData.Id == null) return@let Pair(null, null)
- Pair(
- it.getEpisode("sub", showData.Id, trackers?.idMal),
- it.getEpisode("dub", showData.Id, trackers?.idMal),
- )
- }
-
- val characters = showData.characters?.map {
- val role = when (it.role) {
- "Main" -> ActorRole.Main
- "Supporting" -> ActorRole.Supporting
- "Background" -> ActorRole.Background
- else -> null
- }
- val name = it.name?.full ?: it.name?.native ?: ""
- val image = it.image?.large ?: it.image?.medium
- Pair(Actor(name, image), role)
- }
-
- return newAnimeLoadResponse(title ?: "", url, TvType.Anime) {
- engName = showData.altNames?.firstOrNull()
- posterUrl = trackers?.coverImage?.extraLarge ?: trackers?.coverImage?.large ?: poster
- backgroundPosterUrl = trackers?.bannerImage ?: showData.banner
- rating = showData.averageScore?.times(100)
- tags = showData.genres
- year = showData.airedStart?.year
- duration = showData.episodeDuration?.div(60_000)
- addTrailer(showData.prevideos.filter { it.isNotBlank() }
- .map { "https://www.youtube.com/watch?v=$it" })
- addEpisodes(DubStatus.Subbed, episodes.first)
- addEpisodes(DubStatus.Dubbed, episodes.second)
- addActors(characters)
- //this.recommendations = recommendations
-
- showStatus = getStatus(showData.status.toString())
- addMalId(trackers?.idMal)
- addAniListId(trackers?.id)
- plot = description?.replace(Regex("""<(.*?)>"""), "")
- }
- }
-
- override suspend fun loadLinks(
- data: String,
- isCasting: Boolean,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ): Boolean {
-
- val loadData = parseJson(data)
-
- argamap(
- {
- invokeInternalSources(
- loadData.hash,
- loadData.dubStatus,
- loadData.episode,
- subtitleCallback,
- callback
- )
- },
- {
- invokeExternalSources(
- loadData.idMal,
- loadData.dubStatus,
- loadData.episode,
- subtitleCallback,
- callback
- )
- }
- )
-
- return true
- }
-
- companion object {
- const val apiUrl = BuildConfig.ANICHI_API
- const val serverUrl = BuildConfig.ANICHI_SERVER
- const val apiEndPoint = BuildConfig.ANICHI_ENDPOINT
-
- const val anilistApi = "https://graphql.anilist.co"
- const val jikanApi = "https://api.jikan.moe/v4"
- const val marinHost = "https://marin.moe"
-
- private const val mainHash = "e42a4466d984b2c0a2cecae5dd13aa68867f634b16ee0f17b380047d14482406"
- private const val popularHash = "31a117653812a2547fd981632e8c99fa8bf8a75c4ef1a77a1567ef1741a7ab9c"
- private const val slugHash = "bf603205eb2533ca21d0324a11f623854d62ed838a27e1b3fcfb712ab98b03f4"
- private const val detailHash = "bb263f91e5bdd048c1c978f324613aeccdfe2cbc694a419466a31edb58c0cc0b"
- const val serverHash = "5e7e17cdd0166af5a2d8f43133d9ce3ce9253d1fdb5160a0cfd515564f98d061"
-
- val headers = mapOf(
- "app-version" to "android_c-247",
- "from-app" to BuildConfig.ANICHI_APP,
- "platformstr" to "android_c",
- )
- }
-
-}
\ No newline at end of file
diff --git a/Anichi/src/main/kotlin/com/hexated/AnichiExtractors.kt b/Anichi/src/main/kotlin/com/hexated/AnichiExtractors.kt
deleted file mode 100644
index 86d452ed..00000000
--- a/Anichi/src/main/kotlin/com/hexated/AnichiExtractors.kt
+++ /dev/null
@@ -1,218 +0,0 @@
-package com.hexated
-
-import com.lagradost.cloudstream3.SubtitleFile
-import com.lagradost.cloudstream3.apmap
-import com.lagradost.cloudstream3.app
-import com.lagradost.cloudstream3.argamap
-import com.lagradost.cloudstream3.extractors.helper.GogoHelper
-import com.lagradost.cloudstream3.mvvm.safeApiCall
-import com.lagradost.cloudstream3.utils.AppUtils
-import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
-import com.lagradost.cloudstream3.utils.ExtractorLink
-import com.lagradost.cloudstream3.utils.Qualities
-import com.lagradost.cloudstream3.utils.SubtitleHelper
-import com.lagradost.cloudstream3.utils.httpsify
-import com.lagradost.cloudstream3.utils.loadExtractor
-import java.net.URI
-
-object AnichiExtractors : Anichi() {
-
- suspend fun invokeInternalSources(
- hash: String,
- dubStatus: String,
- episode: String,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit,
- ) {
- val apiUrl =
- """$apiUrl?variables={"showId":"$hash","translationType":"$dubStatus","episodeString":"$episode"}&extensions={"persistedQuery":{"version":1,"sha256Hash":"$serverHash"}}"""
- val apiResponse = app.get(apiUrl, headers = headers).parsed()
-
- apiResponse.data?.episode?.sourceUrls?.apmap { source ->
- safeApiCall {
- val link = fixSourceUrls(source.sourceUrl ?: return@safeApiCall, source.sourceName)
- ?: return@safeApiCall
- if (URI(link).isAbsolute || link.startsWith("//")) {
- val fixedLink = if (link.startsWith("//")) "https:$link" else link
- val host = link.getHost()
-
- when {
- fixedLink.contains(Regex("(?i)playtaku|gogo")) || source.sourceName == "Vid-mp4" -> {
- invokeGogo(fixedLink, subtitleCallback, callback)
- }
-
- embedIsBlacklisted(fixedLink) -> {
- loadExtractor(fixedLink, subtitleCallback, callback)
- }
-
- URI(fixedLink).path.contains(".m3u") -> {
- getM3u8Qualities(fixedLink, serverUrl, host).forEach(callback)
- }
-
- else -> {
- callback(
- ExtractorLink(
- name,
- host,
- fixedLink,
- serverUrl,
- Qualities.P1080.value,
- false
- )
- )
- }
- }
- } else {
- val fixedLink = link.fixUrlPath()
- val links = app.get(fixedLink).parsedSafe()?.links
- ?: emptyList()
- links.forEach { server ->
- val host = server.link.getHost()
- when {
- source.sourceName?.contains("Default") == true -> {
- if (server.resolutionStr == "SUB" || server.resolutionStr == "Alt vo_SUB") {
- getM3u8Qualities(
- server.link,
- "https://static.crunchyroll.com/",
- host,
- ).forEach(callback)
- }
- }
-
- server.hls != null && server.hls -> {
- getM3u8Qualities(
- server.link,
- "$apiEndPoint/player?uri=" + (if (URI(server.link).host.isNotEmpty()) server.link else apiEndPoint + URI(
- server.link
- ).path),
- host
- ).forEach(callback)
- }
-
- else -> {
- callback(
- ExtractorLink(
- host,
- host,
- server.link,
- "$apiEndPoint/player?uri=" + (if (URI(server.link).host.isNotEmpty()) server.link else apiEndPoint + URI(
- server.link
- ).path),
- server.resolutionStr.removeSuffix("p").toIntOrNull()
- ?: Qualities.P1080.value,
- false,
- isDash = server.resolutionStr == "Dash 1"
- )
- )
- server.subtitles?.map { sub ->
- subtitleCallback.invoke(
- SubtitleFile(
- SubtitleHelper.fromTwoLettersToLanguage(sub.lang ?: "")
- ?: sub.lang ?: "",
- httpsify(sub.src ?: return@map)
- )
- )
- }
- }
- }
- }
- }
- }
- }
- }
-
- suspend fun invokeExternalSources(
- idMal: Int? = null,
- dubStatus: String,
- episode: String,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit,
- ) {
- val ids = app.get("https://api.malsync.moe/mal/anime/${idMal ?: return}")
- .parsedSafe()?.sites
-
- if (dubStatus == "sub") invokeMarin(ids?.marin?.keys?.firstOrNull(), episode, callback)
-
- }
-
- private suspend fun invokeMarin(
- id: String? = null,
- episode: String,
- callback: (ExtractorLink) -> Unit
- ) {
- val url = "$marinHost/anime/${id ?: return}/$episode"
- val cookies = app.get(
- "$marinHost/anime",
- headers = mapOf(
- "Cookie" to "__ddg1_=;__ddg2_=;"
- ),
- referer = "$marinHost/anime",
- ).cookies.let {
- decode(it["XSRF-TOKEN"].toString()) to decode(it["marin_session"].toString())
- }
-
- val json = app.get(
- url,
- headers = mapOf(
- "Accept" to "text/html, application/xhtml+xml",
- "Cookie" to "__ddg1=;__ddg2_=;XSRF-TOKEN=${cookies.first};marin_session=${cookies.second};",
- "X-XSRF-TOKEN" to cookies.first
- ),
- referer = "$marinHost/anime/$id"
- ).document.selectFirst("div#app")?.attr("data-page")
- tryParseJson(json)?.props?.video?.data?.mirror?.map { video ->
- callback.invoke(
- ExtractorLink(
- "Marin",
- "Marin",
- video.code?.file ?: return@map,
- url,
- video.code.height ?: Qualities.Unknown.value,
- headers = mapOf(
- "Accept" to "video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5",
- "Accept-Language" to "en-US,en;q=0.5",
- "Cookie" to "__ddg1=;__ddg2_=; XSRF-TOKEN=${cookies.first}; marin_session=${cookies.second};",
- "Connection" to "keep-alive",
- "Sec-Fetch-Dest" to "video",
- "Sec-Fetch-Mode" to "cors",
- "Sec-Fetch-Site" to "cross-site",
- )
- )
- )
- }
- }
-
- private suspend fun invokeGogo(
- link: String,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ) {
- val iframe = app.get(link)
- val iframeDoc = iframe.document
- argamap({
- iframeDoc.select(".list-server-items > .linkserver")
- .forEach { element ->
- val status = element.attr("data-status") ?: return@forEach
- if (status != "1") return@forEach
- val extractorData = element.attr("data-video") ?: return@forEach
- loadExtractor(extractorData, iframe.url, subtitleCallback, callback)
- }
- }, {
- val iv = "3134003223491201"
- val secretKey = "37911490979715163134003223491201"
- val secretDecryptKey = "54674138327930866480207815084989"
- GogoHelper.extractVidstream(
- iframe.url,
- "Gogoanime",
- callback,
- iv,
- secretKey,
- secretDecryptKey,
- isUsingAdaptiveKeys = false,
- isUsingAdaptiveData = true,
- iframeDocument = iframeDoc
- )
- })
- }
-
-}
\ No newline at end of file
diff --git a/Anichi/src/main/kotlin/com/hexated/AnichiParser.kt b/Anichi/src/main/kotlin/com/hexated/AnichiParser.kt
deleted file mode 100644
index 6cbe56ec..00000000
--- a/Anichi/src/main/kotlin/com/hexated/AnichiParser.kt
+++ /dev/null
@@ -1,292 +0,0 @@
-package com.hexated
-
-import com.fasterxml.jackson.annotation.JsonProperty
-
-data class AnichiLoadData(
- val hash: String,
- val dubStatus: String,
- val episode: String,
- val idMal: Int? = null,
-)
-
-data class JikanData(
- @JsonProperty("title") val title: String? = null,
- @JsonProperty("title_english") val title_english: String? = null,
- @JsonProperty("title_japanese") val title_japanese: String? = null,
- @JsonProperty("year") val year: Int? = null,
- @JsonProperty("season") val season: String? = null,
- @JsonProperty("type") val type: String? = null,
-)
-
-data class JikanResponse(
- @JsonProperty("data") val data: JikanData? = null,
-)
-
-data class IdMal(
- @JsonProperty("idMal") val idMal: String? = null,
-)
-
-data class MediaAni(
- @JsonProperty("Media") val media: IdMal? = null,
-)
-
-data class DataAni(
- @JsonProperty("data") val data: MediaAni? = null,
-)
-
-data class CoverImage(
- @JsonProperty("extraLarge") var extraLarge: String? = null,
- @JsonProperty("large") var large: String? = null,
-)
-
-data class AniMedia(
- @JsonProperty("id") var id: Int? = null,
- @JsonProperty("idMal") var idMal: Int? = null,
- @JsonProperty("coverImage") var coverImage: CoverImage? = null,
- @JsonProperty("bannerImage") var bannerImage: String? = null,
-)
-
-data class AniPage(
- @JsonProperty("media") var media: ArrayList = arrayListOf()
-)
-
-data class AniData(
- @JsonProperty("Page") var Page: AniPage? = AniPage()
-)
-
-data class AniSearch(
- @JsonProperty("data") var data: AniData? = AniData()
-)
-
-data class AkIframe(
- @JsonProperty("idUrl") val idUrl: String? = null,
-)
-
-data class Stream(
- @JsonProperty("format") val format: String? = null,
- @JsonProperty("audio_lang") val audio_lang: String? = null,
- @JsonProperty("hardsub_lang") val hardsub_lang: String? = null,
- @JsonProperty("url") val url: String? = null,
-)
-
-data class PortData(
- @JsonProperty("streams") val streams: ArrayList? = arrayListOf(),
-)
-
-data class Subtitles(
- @JsonProperty("lang") val lang: String?,
- @JsonProperty("label") val label: String?,
- @JsonProperty("src") val src: String?,
-)
-
-data class Links(
- @JsonProperty("link") val link: String,
- @JsonProperty("hls") val hls: Boolean?,
- @JsonProperty("resolutionStr") val resolutionStr: String,
- @JsonProperty("src") val src: String?,
- @JsonProperty("portData") val portData: PortData? = null,
- @JsonProperty("subtitles") val subtitles: ArrayList? = arrayListOf(),
-)
-
-data class AnichiVideoApiResponse(
- @JsonProperty("links") val links: List
-)
-
-data class Data(
- @JsonProperty("shows") val shows: Shows? = null,
- @JsonProperty("queryListForTag") val queryListForTag: Shows? = null,
- @JsonProperty("queryPopular") val queryPopular: Shows? = null,
-)
-
-data class Shows(
- @JsonProperty("edges") val edges: List? = arrayListOf(),
- @JsonProperty("recommendations") val recommendations: List? = arrayListOf(),
-)
-
-data class EdgesCard(
- @JsonProperty("anyCard") val anyCard: Edges? = null,
-)
-
-data class CharacterImage(
- @JsonProperty("large") val large: String?,
- @JsonProperty("medium") val medium: String?
-)
-
-data class CharacterName(
- @JsonProperty("full") val full: String?,
- @JsonProperty("native") val native: String?
-)
-
-data class Characters(
- @JsonProperty("image") val image: CharacterImage?,
- @JsonProperty("role") val role: String?,
- @JsonProperty("name") val name: CharacterName?,
-)
-
-data class Edges(
- @JsonProperty("_id") val Id: String?,
- @JsonProperty("name") val name: String?,
- @JsonProperty("englishName") val englishName: String?,
- @JsonProperty("nativeName") val nativeName: String?,
- @JsonProperty("thumbnail") val thumbnail: String?,
- @JsonProperty("type") val type: String?,
- @JsonProperty("season") val season: Season?,
- @JsonProperty("score") val score: Double?,
- @JsonProperty("airedStart") val airedStart: AiredStart?,
- @JsonProperty("availableEpisodes") val availableEpisodes: AvailableEpisodes?,
- @JsonProperty("availableEpisodesDetail") val availableEpisodesDetail: AvailableEpisodesDetail?,
- @JsonProperty("studios") val studios: List?,
- @JsonProperty("genres") val genres: List?,
- @JsonProperty("averageScore") val averageScore: Int?,
- @JsonProperty("characters") val characters: List?,
- @JsonProperty("altNames") val altNames: List?,
- @JsonProperty("description") val description: String?,
- @JsonProperty("status") val status: String?,
- @JsonProperty("banner") val banner: String?,
- @JsonProperty("episodeDuration") val episodeDuration: Int?,
- @JsonProperty("prevideos") val prevideos: List = emptyList(),
-)
-
-data class AvailableEpisodes(
- @JsonProperty("sub") val sub: Int,
- @JsonProperty("dub") val dub: Int,
- @JsonProperty("raw") val raw: Int
-)
-
-data class AiredStart(
- @JsonProperty("year") val year: Int,
- @JsonProperty("month") val month: Int,
- @JsonProperty("date") val date: Int
-)
-
-data class Season(
- @JsonProperty("quarter") val quarter: String,
- @JsonProperty("year") val year: Int
-)
-
-data class AnichiQuery(
- @JsonProperty("data") val data: Data? = null
-)
-
-data class Detail(
- @JsonProperty("data") val data: DetailShow
-)
-
-data class DetailShow(
- @JsonProperty("show") val show: Edges
-)
-
-data class AvailableEpisodesDetail(
- @JsonProperty("sub") val sub: List,
- @JsonProperty("dub") val dub: List,
- @JsonProperty("raw") val raw: List
-)
-
-data class LinksQuery(
- @JsonProperty("data") val data: LinkData? = LinkData()
-)
-
-data class LinkData(
- @JsonProperty("episode") val episode: Episode? = Episode()
-)
-
-data class SourceUrls(
- @JsonProperty("sourceUrl") val sourceUrl: String? = null,
- @JsonProperty("priority") val priority: Int? = null,
- @JsonProperty("sourceName") val sourceName: String? = null,
- @JsonProperty("type") val type: String? = null,
- @JsonProperty("className") val className: String? = null,
- @JsonProperty("streamerId") val streamerId: String? = null
-)
-
-data class Episode(
- @JsonProperty("sourceUrls") val sourceUrls: ArrayList = arrayListOf(),
-)
-
-data class Sub(
- @JsonProperty("hour") val hour: Int? = null,
- @JsonProperty("minute") val minute: Int? = null,
- @JsonProperty("year") val year: Int? = null,
- @JsonProperty("month") val month: Int? = null,
- @JsonProperty("date") val date: Int? = null
-)
-
-data class LastEpisodeDate(
- @JsonProperty("dub") val dub: Sub? = Sub(),
- @JsonProperty("sub") val sub: Sub? = Sub(),
- @JsonProperty("raw") val raw: Sub? = Sub()
-)
-
-data class AnyCard(
- @JsonProperty("_id") val Id: String? = null,
- @JsonProperty("name") val name: String? = null,
- @JsonProperty("englishName") val englishName: String? = null,
- @JsonProperty("nativeName") val nativeName: String? = null,
- @JsonProperty("availableEpisodes") val availableEpisodes: AvailableEpisodes? = null,
- @JsonProperty("score") val score: Double? = null,
- @JsonProperty("lastEpisodeDate") val lastEpisodeDate: LastEpisodeDate? = LastEpisodeDate(),
- @JsonProperty("thumbnail") val thumbnail: String? = null,
- @JsonProperty("lastChapterDate") val lastChapterDate: String? = null,
- @JsonProperty("availableChapters") val availableChapters: String? = null,
- @JsonProperty("__typename") val _typename: String? = null
-)
-
-data class PageStatus(
- @JsonProperty("_id") val Id: String? = null,
- @JsonProperty("views") val views: String? = null,
- @JsonProperty("showId") val showId: String? = null,
- @JsonProperty("rangeViews") val rangeViews: String? = null,
- @JsonProperty("isManga") val isManga: Boolean? = null,
- @JsonProperty("__typename") val _typename: String? = null
-)
-
-
-data class Recommendations(
- @JsonProperty("anyCard") val anyCard: AnyCard? = null,
- @JsonProperty("pageStatus") val pageStatus: PageStatus? = PageStatus(),
- @JsonProperty("__typename") val _typename: String? = null
-)
-
-data class QueryPopular(
- @JsonProperty("total") val total: Int? = null,
- @JsonProperty("recommendations") val recommendations: ArrayList = arrayListOf(),
- @JsonProperty("__typename") val _typename: String? = null
-)
-
-data class DataPopular(
- @JsonProperty("queryPopular") val queryPopular: QueryPopular? = QueryPopular()
-)
-
-data class MALSyncSites(
- @JsonProperty("Zoro") val zoro: HashMap>? = hashMapOf(),
- @JsonProperty("Marin") val marin: HashMap>? = hashMapOf(),
-)
-
-data class MALSyncResponses(
- @JsonProperty("Sites") val sites: MALSyncSites? = null,
-)
-
-data class MarinCode(
- @JsonProperty("file") val file: String? = null,
- @JsonProperty("height") val height: Int? = null,
-)
-
-data class MarinMirror(
- @JsonProperty("code") val code: MarinCode? = null,
-)
-
-data class MarinData(
- @JsonProperty("mirror") val mirror: ArrayList? = arrayListOf(),
-)
-
-data class MarinVideos(
- @JsonProperty("data") val data: MarinData? = null,
-)
-
-data class MarinProps(
- @JsonProperty("video") val video: MarinVideos? = null,
-)
-
-data class MarinResponses(
- @JsonProperty("props") val props: MarinProps? = null,
-)
\ No newline at end of file
diff --git a/Anichi/src/main/kotlin/com/hexated/AnichiPlugin.kt b/Anichi/src/main/kotlin/com/hexated/AnichiPlugin.kt
deleted file mode 100644
index 6fbec8d3..00000000
--- a/Anichi/src/main/kotlin/com/hexated/AnichiPlugin.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package com.hexated
-
-import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
-import com.lagradost.cloudstream3.plugins.Plugin
-import android.content.Context
-
-@CloudstreamPlugin
-class AnichiPlugin: Plugin() {
- override fun load(context: Context) {
- // All providers should be added in this manner. Please don't edit the providers list directly.
- registerMainAPI(Anichi())
- }
-}
\ No newline at end of file
diff --git a/Anichi/src/main/kotlin/com/hexated/AnichiUtils.kt b/Anichi/src/main/kotlin/com/hexated/AnichiUtils.kt
deleted file mode 100644
index 42d3242f..00000000
--- a/Anichi/src/main/kotlin/com/hexated/AnichiUtils.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-package com.hexated
-
-import com.hexated.Anichi.Companion.anilistApi
-import com.hexated.Anichi.Companion.apiEndPoint
-import com.lagradost.cloudstream3.Episode
-import com.lagradost.cloudstream3.app
-import com.lagradost.cloudstream3.base64Decode
-import com.lagradost.cloudstream3.fixTitle
-import com.lagradost.cloudstream3.mvvm.logError
-import com.lagradost.cloudstream3.utils.AppUtils
-import com.lagradost.cloudstream3.utils.AppUtils.toJson
-import com.lagradost.cloudstream3.utils.ExtractorLink
-import com.lagradost.cloudstream3.utils.M3u8Helper
-import com.lagradost.nicehttp.RequestBodyTypes
-import okhttp3.MediaType.Companion.toMediaTypeOrNull
-import okhttp3.RequestBody.Companion.toRequestBody
-import java.net.URI
-import java.net.URLDecoder
-
-suspend fun getTracker(name: String?, altName: String?, year: Int?, season: String?, type: String?): AniMedia? {
- return fetchId(name, year, season, type).takeIf { it?.id != null } ?: fetchId(
- altName,
- year,
- season,
- type
- )
-}
-
-suspend fun fetchId(title: String?, year: Int?, season: String?, type: String?): AniMedia? {
- val query = """
- query (
- ${'$'}page: Int = 1
- ${'$'}search: String
- ${'$'}sort: [MediaSort] = [POPULARITY_DESC, SCORE_DESC]
- ${'$'}type: MediaType
- ${'$'}season: MediaSeason
- ${'$'}year: String
- ${'$'}format: [MediaFormat]
- ) {
- Page(page: ${'$'}page, perPage: 20) {
- media(
- search: ${'$'}search
- sort: ${'$'}sort
- type: ${'$'}type
- season: ${'$'}season
- startDate_like: ${'$'}year
- format_in: ${'$'}format
- ) {
- id
- idMal
- coverImage { extraLarge large }
- bannerImage
- }
- }
- }
- """.trimIndent().trim()
-
- val variables = mapOf(
- "search" to title,
- "sort" to "SEARCH_MATCH",
- "type" to "ANIME",
- "season" to if(type.equals("ona", true)) "" else season?.uppercase(),
- "year" to "$year%",
- "format" to listOf(type?.uppercase())
- ).filterValues { value -> value != null && value.toString().isNotEmpty() }
-
- val data = mapOf(
- "query" to query,
- "variables" to variables
- ).toJson().toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull())
-
- return try {
- app.post(anilistApi, requestBody = data)
- .parsedSafe()?.data?.Page?.media?.firstOrNull()
- } catch (t: Throwable) {
- logError(t)
- null
- }
-
-}
-
-suspend fun aniToMal(id: String): String? {
- return app.post(
- anilistApi, data = mapOf(
- "query" to "{Media(id:$id,type:ANIME){idMal}}",
- )
- ).parsedSafe()?.data?.media?.idMal
-}
-
-fun decode(input: String): String = URLDecoder.decode(input, "utf-8")
-
-private val embedBlackList = listOf(
- "https://mp4upload.com/",
- "https://streamsb.net/",
- "https://dood.to/",
- "https://videobin.co/",
- "https://ok.ru",
- "https://streamlare.com",
- "https://filemoon",
- "streaming.php",
-)
-
-fun embedIsBlacklisted(url: String): Boolean {
- return embedBlackList.any { url.contains(it) }
-}
-
-fun AvailableEpisodesDetail.getEpisode(
- lang: String,
- id: String,
- malId: Int?,
-): List {
- val meta = if (lang == "sub") this.sub else this.dub
- return meta.map { eps ->
- Episode(
- AnichiLoadData(id, lang, eps, malId).toJson(),
- episode = eps.toIntOrNull()
- )
- }.reversed()
-}
-
-suspend fun getM3u8Qualities(
- m3u8Link: String,
- referer: String,
- qualityName: String,
-): List {
- return M3u8Helper.generateM3u8(
- qualityName,
- m3u8Link,
- referer,
- )
-}
-
-fun String.getHost(): String {
- return fixTitle(URI(this).host.substringBeforeLast(".").substringAfterLast("."))
-}
-
-fun String.fixUrlPath() : String {
- return if(this.contains(".json?")) apiEndPoint + this else apiEndPoint + URI(this).path + ".json?" + URI(this).query
-}
-
-fun fixSourceUrls(url: String, source: String?) : String? {
- return if(source == "Ak" || url.contains("/player/vitemb")) {
- AppUtils.tryParseJson(base64Decode(url.substringAfter("=")))?.idUrl
- } else {
- url.replace(" ", "%20")
- }
-}
\ No newline at end of file
diff --git a/Anifreakz/build.gradle.kts b/Anifreakz/build.gradle.kts
deleted file mode 100644
index 83b7a132..00000000
--- a/Anifreakz/build.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-// use an integer for version numbers
-version = 1
-
-
-cloudstream {
- language = "de"
- // All of these properties are optional, you can safely remove them
-
- // description = "Lorem Ipsum"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 0 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "Anime",
- "OVA",
- )
-
- iconUrl = "https://www.google.com/s2/favicons?domain=anifreakz.com&sz=%size%"
-}
\ No newline at end of file
diff --git a/Anifreakz/src/main/AndroidManifest.xml b/Anifreakz/src/main/AndroidManifest.xml
deleted file mode 100644
index c98063f8..00000000
--- a/Anifreakz/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Anifreakz/src/main/kotlin/com/hexated/Anifreakz.kt b/Anifreakz/src/main/kotlin/com/hexated/Anifreakz.kt
deleted file mode 100644
index 32d9b7e4..00000000
--- a/Anifreakz/src/main/kotlin/com/hexated/Anifreakz.kt
+++ /dev/null
@@ -1,193 +0,0 @@
-package com.hexated
-
-import com.lagradost.cloudstream3.*
-import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
-import com.lagradost.cloudstream3.utils.ExtractorLink
-import com.lagradost.cloudstream3.utils.Qualities
-import com.lagradost.cloudstream3.utils.getAndUnpack
-import org.jsoup.nodes.Element
-import java.net.URLDecoder
-
-class Anifreakz : MainAPI() {
- override var mainUrl = "https://anifreakz.com"
- override var name = "Anifreakz"
- override val hasMainPage = true
- override var lang = "de"
- override val hasDownloadSupport = true
-
- override val supportedTypes = setOf(
- TvType.Anime,
- TvType.AnimeMovie,
- TvType.OVA
- )
-
- override val mainPage = mainPageOf(
- "$mainUrl/series?filter=null&page=" to "Anime Neuste",
- "$mainUrl/series?filter={\"sorting\":\"popular\"}&page=" to "Anime Angesagt",
- "$mainUrl/series?filter={\"sorting\":\"released\"}&page=" to "Anime Veröffentlicht",
- "$mainUrl/kalender" to "Anime Kalender",
- )
-
- override suspend fun getMainPage(
- page: Int,
- request: MainPageRequest
- ): HomePageResponse {
- val items = mutableListOf()
- val nonPaged = request.name == "Anime Kalender" && page <= 1
-
- if (!nonPaged) {
- val document = app.get(request.data + page).document
- val home = document.select("div.app-section div.col").mapNotNull {
- it.toSearchResult()
- }
- items.add(HomePageList(request.name, home))
- }
-
- if (nonPaged) {
- val document = app.get(request.data).document
- document.select("div.app-content div.app-section").forEach { block ->
- val header = block.selectFirst("div.app-heading div.text")?.ownText() ?: ""
- val home = block.select("div.col").mapNotNull {
- it.toSearchResult()
- }
- items.add(HomePageList(header, home))
- }
- }
-
- return newHomePageResponse(items)
-
- }
-
- private fun Element.toSearchResult(): AnimeSearchResponse? {
- val href = fixUrl(this.selectFirst("a")?.attr("href") ?: return null)
- val title = this.selectFirst("a.list-title")?.text()?.trim() ?: return null
- val posterUrl = fixUrlNull(this.selectFirst("div.media-cover")?.attr("data-src"))
-
- return newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = posterUrl
- }
- }
-
- override suspend fun search(query: String): List {
- val document = app.get("$mainUrl/search/$query").document
- return document.select("div.app-section div.col").mapNotNull {
- it.toSearchResult()
- }
- }
-
- private fun decode(input: String): String? = URLDecoder.decode(input, "utf-8")
-
- override suspend fun load(url: String): LoadResponse? {
- val document = app.get(url).document
-
- val title =
- document.selectFirst("div.pl-md-4 h1, div.caption-content h1")?.text() ?: return null
- val poster = fixUrlNull(document.selectFirst("div.media.media-cover")?.attr("data-src"))
- val tags = document.select("div.categories a").map { it.text() }
- val rating = document.selectFirst("div.featured-box div:contains(IMDB) div.text")?.text()
- .toRatingInt()
- val year =
- document.selectFirst("div.featured-box div:contains(Veröffentlicht) div.text")?.text()
- ?.trim()?.toIntOrNull()
- val type = if (document.select("div.episodes.tab-content")
- .isNullOrEmpty()
- ) TvType.Movie else TvType.TvSeries
- val description =
- document.select("div.detail-attr div.text-content, div.caption div:contains(Übersicht) div.text")
- .text().trim()
- val trailer = document.selectFirst("button:contains(Trailer)")?.attr("data-remote")
- ?.substringAfter("?trailer=")?.let {
- decode(it)
- }
-
- return if (type == TvType.Movie) {
- newMovieLoadResponse(title, url, type, url) {
- posterUrl = poster
- this.year = year
- this.rating = rating
- plot = description
- this.tags = tags
- addTrailer(trailer)
- }
- } else {
- val subEpisodes = mutableListOf()
- document.select("div.episodes.tab-content div[id*=season-]").forEach { season ->
- val seasonNum = season.attr("id").substringAfterLast("-").toIntOrNull()
- season.select("a").map { eps ->
- val href = eps.attr("href")
- val name = eps.select("div.name").text()
- val episode =
- eps.select("div.episode").text().substringBefore(".").toIntOrNull()
- val episodes = Episode(
- href,
- name,
- seasonNum,
- episode
- )
- subEpisodes.add(episodes)
- }
- }
- newAnimeLoadResponse(title, url, type) {
- posterUrl = poster
- this.year = year
- addEpisodes(DubStatus.Subbed, subEpisodes)
- this.rating = rating
- plot = description
- this.tags = tags
- addTrailer(trailer)
- }
- }
-
- }
-
- override suspend fun loadLinks(
- data: String,
- isCasting: Boolean,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ): Boolean {
- val document = app.get(data).document
-
- val servers = mutableListOf>()
-
- document.select("div[aria-labelledby=videoSource] button").map {
- servers.add(it.attr("data-embed") to it.text())
- }
-
- document.select("div.nav-player-select a").map {
- servers.add(it.attr("data-embed") to it.select("span").text())
- }
-
- servers.distinctBy { it.first }.apmap { (id, source) ->
- val iframe = app.post(
- "$mainUrl/ajax/embed",
- data = mapOf("id" to id, "captcha" to ""),
- headers = mapOf(
- "X-Requested-With" to "XMLHttpRequest"
- ),
- referer = data
- ).document.select("iframe").attr("src")
- val doc = app.get(iframe, referer = "$mainUrl/").document
- val link =
- unpackJs(doc)?.substringAfter("file:\"")?.substringBefore("\"") ?: return@apmap null
- callback.invoke(
- ExtractorLink(
- source,
- source,
- link,
- "https://filemoon.sx/",
- Qualities.Unknown.value,
- isM3u8 = link.contains(".m3u8")
- )
- )
- }
-
- return true
- }
-
- private fun unpackJs(script: Element): String? {
- return script.select("script").find { it.data().contains("eval(function(p,a,c,k,e,d)") }
- ?.data()?.let { getAndUnpack(it) }
- }
-
-}
\ No newline at end of file
diff --git a/Anifreakz/src/main/kotlin/com/hexated/AnifreakzPlugin.kt b/Anifreakz/src/main/kotlin/com/hexated/AnifreakzPlugin.kt
deleted file mode 100644
index 5de45031..00000000
--- a/Anifreakz/src/main/kotlin/com/hexated/AnifreakzPlugin.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package com.hexated
-
-import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
-import com.lagradost.cloudstream3.plugins.Plugin
-import android.content.Context
-
-@CloudstreamPlugin
-class AnifreakzPlugin: Plugin() {
- override fun load(context: Context) {
- // All providers should be added in this manner. Please don't edit the providers list directly.
- registerMainAPI(Anifreakz())
- }
-}
\ No newline at end of file
diff --git a/Anilibria/build.gradle.kts b/Anilibria/build.gradle.kts
deleted file mode 100644
index 061d5f39..00000000
--- a/Anilibria/build.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-// use an integer for version numbers
-version = 2
-
-
-cloudstream {
- language = "ru"
- // All of these properties are optional, you can safely remove them
-
- // description = "Lorem Ipsum"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 1 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "OVA",
- "Anime",
- )
-
- iconUrl = "https://raw.githubusercontent.com/hexated/cloudstream-extensions-hexated/master/Anilibria/icon.png"
-}
\ No newline at end of file
diff --git a/Anilibria/icon.png b/Anilibria/icon.png
deleted file mode 100644
index 844b3684..00000000
Binary files a/Anilibria/icon.png and /dev/null differ
diff --git a/Anilibria/src/main/AndroidManifest.xml b/Anilibria/src/main/AndroidManifest.xml
deleted file mode 100644
index c98063f8..00000000
--- a/Anilibria/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Anilibria/src/main/kotlin/com/hexated/Anilibria.kt b/Anilibria/src/main/kotlin/com/hexated/Anilibria.kt
deleted file mode 100644
index c51afb3c..00000000
--- a/Anilibria/src/main/kotlin/com/hexated/Anilibria.kt
+++ /dev/null
@@ -1,197 +0,0 @@
-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.AppUtils.tryParseJson
-import com.lagradost.cloudstream3.utils.ExtractorLink
-import com.lagradost.cloudstream3.utils.getQualityFromName
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Element
-
-class Anilibria : MainAPI() {
- override var mainUrl = "https://anilibria.tv"
- override var name = "Anilibria"
- override val hasMainPage = true
- override var lang = "ru"
- override val hasDownloadSupport = true
-
- override val supportedTypes = setOf(
- TvType.Anime,
- TvType.AnimeMovie,
- TvType.OVA
- )
-
- companion object {
- fun getType(t: String): TvType {
- return when {
- t.contains("Фильм", true) -> TvType.Movie
- t.contains("ТВ", true) -> TvType.Anime
- else -> TvType.OVA
- }
- }
- }
-
- override val mainPage = mainPageOf(
- "1" to "Новое",
- "2" to "Популярное",
- )
-
- override suspend fun getMainPage(
- page: Int,
- request: MainPageRequest
- ): HomePageResponse {
- val document = app.post(
- "$mainUrl/public/catalog.php", data = mapOf(
- "page" to "$page",
- "xpage" to "catalog",
- "sort" to request.data,
- "finish" to "1",
- "search" to "{\"year\":\"\",\"genre\":\"\",\"season\":\"\"}"
- ), headers = mapOf("X-Requested-With" to "XMLHttpRequest")
- ).parsedSafe()?.table?.let { Jsoup.parse(it) }
- val home = document?.select("a")?.mapNotNull {
- it.toSearchResult()
- } ?: throw ErrorLoadingException("Invalid json responses")
- return newHomePageResponse(request.name, home)
- }
-
- private fun Element.toSearchResult(): AnimeSearchResponse? {
- val href = fixUrl(this.attr("href"))
- val title = this.selectFirst("span")?.text() ?: return null
- val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("src"))
-
- return newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = posterUrl
- addDubStatus(isDub = true)
- }
- }
-
- override suspend fun search(query: String): List {
- val document = app.post(
- "$mainUrl/public/search.php",
- data = mapOf("search" to query, "small" to "1"),
- headers = mapOf("X-Requested-With" to "XMLHttpRequest")
- ).parsedSafe()?.mes?.let { Jsoup.parse(it) }
-
- return document?.select("a")?.mapNotNull {
- it.toSearchResult()
- } ?: throw ErrorLoadingException("Invalid json responses")
- }
-
- override suspend fun load(url: String): LoadResponse? {
- val document = app.get(url).document
-
- val title = document.selectFirst("h1.release-title")?.text() ?: return null
- val poster = fixUrlNull(document.selectFirst("img#adminPoster")?.attr("src"))
- val trackTitle = (document.selectFirst("h1.release-title br")?.nextSibling()
- ?: document.selectFirst("h1.release-title")?.text()?.substringAfter("/")?.trim()).toString()
- val type = document.selectFirst("div#xreleaseInfo b:contains(Тип:)")?.nextSibling()
- .toString().substringBefore(",").trim()
- val trackType = type.let {
- if(it.contains("Фильм", true)) "movie" else "tv"
- }
- val year = document.selectFirst("div#xreleaseInfo b:contains(Сезон:)")?.nextElementSibling()
- ?.text()?.filter { it.isDigit() }?.toIntOrNull()
- val (malId, anilistId, image, cover) = getTracker(trackTitle, trackType, year)
- val episodes = document.select("script").find { it.data().contains("var player =") }?.data()
- ?.substringAfter("file:[")?.substringBefore("],")?.let { data ->
- tryParseJson>("[$data]")?.mapNotNull { eps ->
- Episode(
- eps.file ?: return@mapNotNull null,
- name = eps.title ?: return@mapNotNull null,
- posterUrl = fixUrlNull(eps.poster),
- )
- }
- }
- return newAnimeLoadResponse(title, url, getType(type)) {
- posterUrl = image ?: poster
- backgroundPosterUrl = cover ?: image ?: poster
- this.year = year
- addEpisodes(DubStatus.Subbed, episodes)
- plot = document.select("p.detail-description").text().trim()
- this.tags = document.selectFirst("div#xreleaseInfo b:contains(Жанры:)")?.nextSibling()
- .toString().split(",").map { it.trim() }
- addMalId(malId)
- addAniListId(anilistId?.toIntOrNull())
- }
- }
-
- override suspend fun loadLinks(
- data: String,
- isCasting: Boolean,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ): Boolean {
-
- data.split(",").map { it.trim() }.map { m3u ->
- val quality = Regex("\\[([0-9]+p)]").find(m3u)?.groupValues?.getOrNull(1)
- val link = m3u.removePrefix("[$quality]").trim()
- callback.invoke(
- ExtractorLink(
- this.name,
- this.name,
- link,
- "$mainUrl/",
- getQualityFromName(quality),
- true
- )
- )
- }
-
- return true
- }
-
- private suspend fun getTracker(title: String?, type: String?, year: Int?): Tracker {
- val res = app.get("https://api.consumet.org/meta/anilist/$title")
- .parsedSafe()?.results?.find { media ->
- (media.title?.english.equals(title, true) || media.title?.romaji.equals(
- title,
- true
- )) || (media.type.equals(type, true) && media.releaseDate == year)
- }
- return Tracker(res?.malId, res?.aniId, res?.image, res?.cover)
- }
-
- data class Tracker(
- val malId: Int? = null,
- val aniId: String? = null,
- val image: String? = null,
- val cover: String? = null,
- )
-
- data class Title(
- @JsonProperty("romaji") val romaji: String? = null,
- @JsonProperty("english") val english: String? = null,
- )
-
- data class Results(
- @JsonProperty("id") val aniId: String? = null,
- @JsonProperty("malId") val malId: Int? = null,
- @JsonProperty("title") val title: Title? = null,
- @JsonProperty("releaseDate") val releaseDate: Int? = null,
- @JsonProperty("type") val type: String? = null,
- @JsonProperty("image") val image: String? = null,
- @JsonProperty("cover") val cover: String? = null,
- )
-
- data class AniSearch(
- @JsonProperty("results") val results: ArrayList? = arrayListOf(),
- )
-
- private data class Episodes(
- @JsonProperty("file") val file: String? = null,
- @JsonProperty("title") val title: String? = null,
- @JsonProperty("poster") val poster: String? = null,
- )
-
- private data class Home(
- @JsonProperty("table") val table: String? = null,
- )
-
- private data class Search(
- @JsonProperty("mes") val mes: String? = null,
- )
-
-}
\ No newline at end of file
diff --git a/Anilibria/src/main/kotlin/com/hexated/AnilibriaPlugin.kt b/Anilibria/src/main/kotlin/com/hexated/AnilibriaPlugin.kt
deleted file mode 100644
index d813fb25..00000000
--- a/Anilibria/src/main/kotlin/com/hexated/AnilibriaPlugin.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package com.hexated
-
-import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
-import com.lagradost.cloudstream3.plugins.Plugin
-import android.content.Context
-
-@CloudstreamPlugin
-class AnilibriaPlugin: Plugin() {
- override fun load(context: Context) {
- // All providers should be added in this manner. Please don't edit the providers list directly.
- registerMainAPI(Anilibria())
- }
-}
\ No newline at end of file
diff --git a/Animasu/build.gradle.kts b/Animasu/build.gradle.kts
deleted file mode 100644
index 24d134e7..00000000
--- a/Animasu/build.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-// use an integer for version numbers
-version = 9
-
-
-cloudstream {
- language = "id"
- // All of these properties are optional, you can safely remove them
-
- // description = "Lorem Ipsum"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 1 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "OVA",
- "Anime",
- )
-
- iconUrl = "https://www.google.com/s2/favicons?domain=animasu.cc&sz=%size%"
-}
\ No newline at end of file
diff --git a/Animasu/src/main/AndroidManifest.xml b/Animasu/src/main/AndroidManifest.xml
deleted file mode 100644
index 874740e3..00000000
--- a/Animasu/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Animasu/src/main/kotlin/com/hexated/Animasu.kt b/Animasu/src/main/kotlin/com/hexated/Animasu.kt
deleted file mode 100644
index 2b1cdf7d..00000000
--- a/Animasu/src/main/kotlin/com/hexated/Animasu.kt
+++ /dev/null
@@ -1,191 +0,0 @@
-package com.hexated
-
-import com.lagradost.cloudstream3.*
-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.*
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Element
-
-class Animasu : MainAPI() {
- override var mainUrl = "https://animasu.win"
- override var name = "Animasu"
- override val hasMainPage = true
- override var lang = "id"
- override val hasDownloadSupport = true
-
- override val supportedTypes = setOf(
- TvType.Anime,
- TvType.AnimeMovie,
- TvType.OVA
- )
-
- companion object {
- fun getType(t: String?): TvType {
- if(t == null) return TvType.Anime
- return when {
- t.contains("Tv", true) -> TvType.Anime
- t.contains("Movie", true) -> TvType.AnimeMovie
- t.contains("OVA", true) || t.contains("Special", true) -> TvType.OVA
- else -> TvType.Anime
- }
- }
-
- fun getStatus(t: String?): ShowStatus {
- if(t == null) return ShowStatus.Completed
- return when {
- t.contains("Sedang Tayang", true) -> ShowStatus.Ongoing
- else -> ShowStatus.Completed
- }
- }
- }
-
- override val mainPage = mainPageOf(
- "urutan=update" to "Baru diupdate",
- "status=&tipe=&urutan=publikasi" to "Baru ditambahkan",
- "status=&tipe=&urutan=populer" to "Terpopuler",
- "status=&tipe=&urutan=rating" to "Rating Tertinggi",
- "status=&tipe=Movie&urutan=update" to "Movie Terbaru",
- "status=&tipe=Movie&urutan=populer" to "Movie Terpopuler",
- )
-
- override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
- val document = app.get("$mainUrl/pencarian/?${request.data}&halaman=$page").document
- val home = document.select("div.listupd div.bs").map {
- it.toSearchResult()
- }
- return newHomePageResponse(request.name, home)
- }
-
- private fun getProperAnimeLink(uri: String): String {
- return if (uri.contains("/anime/")) {
- uri
- } else {
- var title = uri.substringAfter("$mainUrl/")
- title = when {
- (title.contains("-episode")) && !(title.contains("-movie")) -> title.substringBefore(
- "-episode"
- )
-
- (title.contains("-movie")) -> title.substringBefore("-movie")
- else -> title
- }
-
- "$mainUrl/anime/$title"
- }
- }
-
- private fun Element.toSearchResult(): AnimeSearchResponse {
- val href = getProperAnimeLink(fixUrlNull(this.selectFirst("a")?.attr("href")).toString())
- val title = this.select("div.tt").text().trim()
- val posterUrl = fixUrlNull(this.selectFirst("img")?.getImageAttr())
- val epNum = this.selectFirst("span.epx")?.text()?.filter { it.isDigit() }?.toIntOrNull()
- return newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = posterUrl
- addSub(epNum)
- }
-
- }
-
- override suspend fun search(query: String): List {
- return app.get("$mainUrl/?s=$query").document.select("div.listupd div.bs").map {
- it.toSearchResult()
- }
- }
-
- override suspend fun load(url: String): LoadResponse {
- val document = app.get(url).document
-
- val title = document.selectFirst("div.infox h1")?.text().toString().replace("Sub Indo", "").trim()
- val poster = document.selectFirst("div.bigcontent img")?.getImageAttr()
-
- val table = document.selectFirst("div.infox div.spe")
- val type = getType(table?.selectFirst("span:contains(Jenis:)")?.ownText())
- val year = table?.selectFirst("span:contains(Rilis:)")?.ownText()?.substringAfterLast(",")?.trim()?.toIntOrNull()
- val status = table?.selectFirst("span:contains(Status:) font")?.text()
- val trailer = document.selectFirst("div.trailer iframe")?.attr("src")
- val episodes = document.select("ul#daftarepisode > li").map {
- val link = fixUrl(it.selectFirst("a")!!.attr("href"))
- val name = it.selectFirst("a")?.text() ?: ""
- val episode = Regex("Episode\\s?(\\d+)").find(name)?.groupValues?.getOrNull(0)?.toIntOrNull()
- Episode(link, episode = episode)
- }.reversed()
-
- val tracker = APIHolder.getTracker(listOf(title),TrackerType.getTypes(type),year,true)
-
- return newAnimeLoadResponse(title, url, type) {
- posterUrl = tracker?.image ?: poster
- backgroundPosterUrl = tracker?.cover
- this.year = year
- addEpisodes(DubStatus.Subbed, episodes)
- showStatus = getStatus(status)
- plot = document.select("div.sinopsis p").text()
- this.tags = table?.select("span:contains(Genre:) a")?.map { it.text() }
- addTrailer(trailer)
- addMalId(tracker?.malId)
- addAniListId(tracker?.aniId?.toIntOrNull())
- }
- }
-
- override suspend fun loadLinks(
- data: String,
- isCasting: Boolean,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ): Boolean {
- val document = app.get(data).document
- document.select(".mobius > .mirror > option").mapNotNull {
- fixUrl(Jsoup.parse(base64Decode(it.attr("value"))).select("iframe").attr("src")) to it.text()
- }.apmap { (iframe, quality) ->
- loadFixedExtractor(iframe.fixIframe(), quality, "$mainUrl/", subtitleCallback, callback)
- }
- return true
- }
-
- private suspend fun loadFixedExtractor(
- url: String,
- quality: String?,
- referer: String? = null,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ) {
- loadExtractor(url, referer, subtitleCallback) { link ->
- callback.invoke(
- ExtractorLink(
- link.name,
- link.name,
- link.url,
- link.referer,
- if(link.type == ExtractorLinkType.M3U8 || link.name == "Uservideo") link.quality else getIndexQuality(quality),
- link.type,
- link.headers,
- link.extractorData
- )
- )
- }
- }
-
- private fun String.fixIframe() : String {
- return if(this.startsWith("https://dl.berkasdrive.com")) {
- base64Decode(this.substringAfter("id="))
- } else {
- this
- }
- }
-
- private fun getIndexQuality(str: String?): Int {
- return Regex("(\\d{3,4})[pP]").find(str ?: "")?.groupValues?.getOrNull(1)?.toIntOrNull()
- ?: Qualities.Unknown.value
- }
-
- private fun Element.getImageAttr(): String? {
- return when {
- this.hasAttr("data-src") -> this.attr("abs:data-src")
- this.hasAttr("data-lazy-src") -> this.attr("abs:data-lazy-src")
- this.hasAttr("srcset") -> this.attr("abs:srcset").substringBefore(" ")
- else -> this.attr("abs:src")
- }
- }
-
-}
\ No newline at end of file
diff --git a/Animasu/src/main/kotlin/com/hexated/AnimasuPlugin.kt b/Animasu/src/main/kotlin/com/hexated/AnimasuPlugin.kt
deleted file mode 100644
index 5ef35841..00000000
--- a/Animasu/src/main/kotlin/com/hexated/AnimasuPlugin.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-
-package com.hexated
-
-import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
-import com.lagradost.cloudstream3.plugins.Plugin
-import android.content.Context
-
-@CloudstreamPlugin
-class AnimasuPlugin: Plugin() {
- override fun load(context: Context) {
- // All providers should be added in this manner. Please don't edit the providers list directly.
- registerMainAPI(Animasu())
- registerExtractorAPI(Archivd())
- registerExtractorAPI(Newuservideo())
- registerExtractorAPI(Vidhidepro())
- }
-}
\ No newline at end of file
diff --git a/Animasu/src/main/kotlin/com/hexated/Extractors.kt b/Animasu/src/main/kotlin/com/hexated/Extractors.kt
deleted file mode 100644
index dfd08840..00000000
--- a/Animasu/src/main/kotlin/com/hexated/Extractors.kt
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.hexated
-
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.lagradost.cloudstream3.SubtitleFile
-import com.lagradost.cloudstream3.*
-import com.lagradost.cloudstream3.extractors.Filesim
-import com.lagradost.cloudstream3.utils.AppUtils
-import com.lagradost.cloudstream3.utils.ExtractorApi
-import com.lagradost.cloudstream3.utils.ExtractorLink
-import com.lagradost.cloudstream3.utils.INFER_TYPE
-import com.lagradost.cloudstream3.utils.Qualities
-
-class Archivd : ExtractorApi() {
- override val name: String = "Archivd"
- override val mainUrl: String = "https://archivd.net"
- override val requiresReferer = true
-
- override suspend fun getUrl(
- url: String,
- referer: String?,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ) {
- val res = app.get(url).document
- val json = res.select("div#app").attr("data-page")
- val video = AppUtils.tryParseJson(json)?.props?.datas?.data?.link?.media
- callback.invoke(
- ExtractorLink(
- this.name,
- this.name,
- video ?: return,
- "$mainUrl/",
- Qualities.Unknown.value,
- INFER_TYPE
- )
- )
- }
-
- data class Link(
- @JsonProperty("media") val media: String? = null,
- )
-
- data class Data(
- @JsonProperty("link") val link: Link? = null,
- )
-
- data class Datas(
- @JsonProperty("data") val data: Data? = null,
- )
-
- data class Props(
- @JsonProperty("datas") val datas: Datas? = null,
- )
-
- data class Sources(
- @JsonProperty("props") val props: Props? = null,
- )
-}
-
-class Newuservideo : ExtractorApi() {
- override val name: String = "Uservideo"
- override val mainUrl: String = "https://new.uservideo.xyz"
- override val requiresReferer = true
-
- override suspend fun getUrl(
- url: String,
- referer: String?,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ) {
- val iframe = app.get(url,referer=referer).document.select("iframe#videoFrame").attr("src")
- val doc = app.get(iframe,referer="$mainUrl/").text
- val json = "VIDEO_CONFIG\\s?=\\s?(.*)".toRegex().find(doc)?.groupValues?.get(1)
-
- AppUtils.tryParseJson(json)?.streams?.map {
- callback.invoke(
- ExtractorLink(
- this.name,
- this.name,
- it.playUrl ?: return@map,
- "$mainUrl/",
- when (it.formatId) {
- 18 -> Qualities.P360.value
- 22 -> Qualities.P720.value
- else -> Qualities.Unknown.value
- },
- INFER_TYPE
- )
- )
- }
-
- }
-
- data class Streams(
- @JsonProperty("play_url") val playUrl: String? = null,
- @JsonProperty("format_id") val formatId: Int? = null,
- )
-
- data class Sources(
- @JsonProperty("streams") val streams: ArrayList? = null,
- )
-
-}
-
-class Vidhidepro : Filesim() {
- override val mainUrl = "https://vidhidepro.com"
- override val name = "Vidhidepro"
-}
\ No newline at end of file
diff --git a/AnimeIndoProvider/build.gradle.kts b/AnimeIndoProvider/build.gradle.kts
deleted file mode 100644
index af852c5c..00000000
--- a/AnimeIndoProvider/build.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-// use an integer for version numbers
-version = 15
-
-
-cloudstream {
- language = "id"
- // All of these properties are optional, you can safely remove them
-
- // description = "Lorem Ipsum"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 1 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "OVA",
- "Anime",
- )
-
- iconUrl = "https://www.google.com/s2/favicons?domain=animeindo.fun&sz=%size%"
-}
\ No newline at end of file
diff --git a/AnimeIndoProvider/src/main/AndroidManifest.xml b/AnimeIndoProvider/src/main/AndroidManifest.xml
deleted file mode 100644
index 874740e3..00000000
--- a/AnimeIndoProvider/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt
deleted file mode 100644
index fcf6489c..00000000
--- a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt
+++ /dev/null
@@ -1,175 +0,0 @@
-package com.hexated
-
-import com.lagradost.cloudstream3.*
-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.httpsify
-import com.lagradost.cloudstream3.utils.loadExtractor
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Element
-
-class AnimeIndoProvider : MainAPI() {
- override var mainUrl = "https://animeindo.quest"
- override var name = "AnimeIndo"
- override val hasMainPage = true
- override var lang = "id"
- override val supportedTypes = setOf(
- TvType.Anime,
- TvType.AnimeMovie,
- TvType.OVA
- )
-
- companion object {
- fun getType(t: String): TvType {
- return if (t.contains("OVA", true) || t.contains("Special")) TvType.OVA
- else if (t.contains("Movie", true)) TvType.AnimeMovie
- else TvType.Anime
- }
-
- fun getStatus(t: String): ShowStatus {
- return when (t) {
- "Finished Airing" -> ShowStatus.Completed
- "Currently Airing" -> ShowStatus.Ongoing
- else -> ShowStatus.Completed
- }
- }
-
- }
-
- override val mainPage = mainPageOf(
- "episode-terbaru" to "Episode Terbaru",
- "ongoing" to "Anime Ongoing",
- "populer" to "Anime Populer",
- "donghua-terbaru" to "Donghua Terbaru",
- )
-
- override suspend fun getMainPage(
- page: Int,
- request: MainPageRequest
- ): HomePageResponse {
- val document = app.get("$mainUrl/${request.data}/page/$page").document
- val home = document.select("main#main div.animposx").mapNotNull {
- it.toSearchResult()
- }
- return newHomePageResponse(request.name, home)
- }
-
- private fun getProperAnimeLink(uri: String): String {
- return if (uri.contains("/anime/")) {
- uri
- } else {
- var title = uri.substringAfter("$mainUrl/")
- title = when {
- (title.contains("-episode")) && !(title.contains("-movie")) -> title.substringBefore(
- "-episode"
- )
-
- (title.contains("-movie")) -> title.substringBefore("-movie")
- else -> title
- }
-
- "$mainUrl/anime/$title"
- }
- }
-
- private fun Element.toSearchResult(): AnimeSearchResponse {
- val title = this.selectFirst("div.title, h2.entry-title, h4")?.text()?.trim() ?: ""
- val href = getProperAnimeLink(this.selectFirst("a")!!.attr("href"))
- val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("src"))
- val epNum = this.selectFirst("span.episode")?.ownText()?.replace(Regex("\\D"), "")?.trim()
- ?.toIntOrNull()
- return newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = posterUrl
- addSub(epNum)
- }
-
- }
-
- override suspend fun search(query: String): List {
- val anime = mutableListOf()
- (1..2).forEach { page ->
- val document = app.get("$mainUrl/page/$page/?s=$query").document
- val media = document.select(".site-main.relat > article").mapNotNull {
- val title = it.selectFirst("div.title > h2")!!.ownText().trim()
- val href = it.selectFirst("a")!!.attr("href")
- val posterUrl = it.selectFirst("img")!!.attr("src").toString()
- val type = getType(it.select("div.type").text().trim())
- newAnimeSearchResponse(title, href, type) {
- this.posterUrl = posterUrl
- }
- }
- if(media.isNotEmpty()) anime.addAll(media)
- }
- return anime
- }
-
- override suspend fun load(url: String): LoadResponse? {
- val document = app.get(url).document
- 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:contains(Type:)")?.ownText()
- ?.trim()?.lowercase() ?: "tv")
- val year = document.selectFirst("div.info-content > div.spe > span:contains(Released:)")?.ownText()?.let {
- Regex("\\d,\\s(\\d*)").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 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 episode = header.text().trim().replace("Episode", "").trim().toIntOrNull()
- val link = fixUrl(header.attr("href"))
- Episode(link, episode = episode)
- }.reversed()
-
- val recommendations = document.select("div.relat div.animposx").mapNotNull {
- it.toSearchResult()
- }
-
- val tracker = APIHolder.getTracker(listOf(title),TrackerType.getTypes(type),year,true)
-
- return newAnimeLoadResponse(title, url, type) {
- engName = title
- posterUrl = tracker?.image ?: poster
- backgroundPosterUrl = tracker?.cover
- this.year = year
- addEpisodes(DubStatus.Subbed, episodes)
- showStatus = status
- plot = description
- this.tags = tags
- this.recommendations = recommendations
- addTrailer(trailer)
- addMalId(tracker?.malId)
- addAniListId(tracker?.aniId?.toIntOrNull())
- }
- }
-
- override suspend fun loadLinks(
- data: String,
- isCasting: Boolean,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ): Boolean {
-
- val document = app.get(data).document
- document.select("div.itemleft > .mirror > option").mapNotNull {
- fixUrl(Jsoup.parse(base64Decode(it.attr("value"))).select("iframe").attr("src"))
- }.apmap {
- if (it.startsWith(mainUrl)) {
- app.get(it, referer = "$mainUrl/").document.select("iframe").attr("src")
- } else {
- it
- }
- }.apmap {
- loadExtractor(httpsify(it), data, subtitleCallback, callback)
- }
-
- return true
- }
-
-}
\ No newline at end of file
diff --git a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProviderPlugin.kt b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProviderPlugin.kt
deleted file mode 100644
index 7f4d0a0d..00000000
--- a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProviderPlugin.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package com.hexated
-
-import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
-import com.lagradost.cloudstream3.plugins.Plugin
-import android.content.Context
-
-@CloudstreamPlugin
-class AnimeIndoProviderPlugin: Plugin() {
- override fun load(context: Context) {
- // All providers should be added in this manner. Please don't edit the providers list directly.
- registerMainAPI(AnimeIndoProvider())
- }
-}
\ No newline at end of file
diff --git a/AnimeSailProvider/build.gradle.kts b/AnimeSailProvider/build.gradle.kts
deleted file mode 100644
index cea32bdc..00000000
--- a/AnimeSailProvider/build.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-// use an integer for version numbers
-version = 10
-
-
-cloudstream {
- language = "id"
- // All of these properties are optional, you can safely remove them
-
- // description = "Lorem Ipsum"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 1 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "Anime",
- "OVA",
- )
-
- iconUrl = "https://aghanim.xyz/wp-content/themes/animesail/assets/images/ico.png"
-}
\ No newline at end of file
diff --git a/AnimeSailProvider/src/main/AndroidManifest.xml b/AnimeSailProvider/src/main/AndroidManifest.xml
deleted file mode 100644
index 874740e3..00000000
--- a/AnimeSailProvider/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt b/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt
deleted file mode 100644
index 721121a2..00000000
--- a/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt
+++ /dev/null
@@ -1,230 +0,0 @@
-package com.hexated
-
-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.ExtractorLinkType
-import com.lagradost.cloudstream3.utils.Qualities
-import com.lagradost.cloudstream3.utils.loadExtractor
-import com.lagradost.nicehttp.NiceResponse
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Element
-
-class AnimeSailProvider : MainAPI() {
- override var mainUrl = "https://154.26.137.28"
- override var name = "AnimeSail"
- override val hasMainPage = true
- override var lang = "id"
- override val hasDownloadSupport = true
-
- override val supportedTypes = setOf(
- TvType.Anime,
- TvType.AnimeMovie,
- TvType.OVA
- )
-
- companion object {
- fun getType(t: String): TvType {
- return if (t.contains("OVA", true) || t.contains("Special")) TvType.OVA
- else if (t.contains("Movie", true)) TvType.AnimeMovie
- else TvType.Anime
- }
-
- fun getStatus(t: String): ShowStatus {
- return when (t) {
- "Completed" -> ShowStatus.Completed
- "Ongoing" -> ShowStatus.Ongoing
- else -> ShowStatus.Completed
- }
- }
- }
-
- private suspend fun request(url: String, ref: String? = null): NiceResponse {
- return app.get(
- url,
- headers = mapOf("Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"),
- cookies = mapOf("_as_ipin_ct" to "ID"),
- referer = ref
- )
- }
-
- override val mainPage = mainPageOf(
- "$mainUrl/page/" to "Episode Terbaru",
- "$mainUrl/movie-terbaru/page/" to "Movie Terbaru",
- "$mainUrl/genres/donghua/page/" to "Donghua"
- )
-
- override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
- val document = request(request.data + page).document
- val home = document.select("article").map {
- it.toSearchResult()
- }
- return newHomePageResponse(request.name, home)
- }
-
- private fun getProperAnimeLink(uri: String): String {
- return if (uri.contains("/anime/")) {
- uri
- } else {
- var title = uri.substringAfter("$mainUrl/")
- title = when {
- (title.contains("-episode")) && !(title.contains("-movie")) -> title.substringBefore(
- "-episode"
- )
- (title.contains("-movie")) -> title.substringBefore("-movie")
- else -> title
- }
-
- "$mainUrl/anime/$title"
- }
- }
-
- private fun Element.toSearchResult(): AnimeSearchResponse {
- val href = getProperAnimeLink(fixUrlNull(this.selectFirst("a")?.attr("href")).toString())
- val title = this.select(".tt > h2").text().trim()
- val posterUrl = fixUrlNull(this.selectFirst("div.limit img")?.attr("src"))
- val epNum = this.selectFirst(".tt > h2")?.text()?.let {
- Regex("Episode\\s?(\\d+)").find(it)?.groupValues?.getOrNull(1)?.toIntOrNull()
- }
- return newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = posterUrl
- addSub(epNum)
- }
-
- }
-
- override suspend fun search(query: String): List {
- val link = "$mainUrl/?s=$query"
- val document = request(link).document
-
- return document.select("div.listupd article").map {
- it.toSearchResult()
- }
- }
-
- override suspend fun load(url: String): LoadResponse {
- val document = request(url).document
-
- val title = document.selectFirst("h1.entry-title")?.text().toString()
- .replace("Subtitle Indonesia", "").trim()
- val poster = document.selectFirst("div.entry-content > img")?.attr("src")
- val type = getType(document.select("tbody th:contains(Tipe)").next().text().lowercase())
- val year = document.select("tbody th:contains(Dirilis)").next().text().trim().toIntOrNull()
-
- val episodes = document.select("ul.daftar > li").map {
- val link = fixUrl(it.select("a").attr("href"))
- val name = it.select("a").text()
- val episode = Regex("Episode\\s?(\\d+)").find(name)?.groupValues?.getOrNull(0)?.toIntOrNull()
- Episode(link, episode = episode)
- }.reversed()
-
- val tracker = APIHolder.getTracker(listOf(title),TrackerType.getTypes(type),year,true)
-
- return newAnimeLoadResponse(title, url, type) {
- posterUrl = tracker?.image ?: poster
- backgroundPosterUrl = tracker?.cover
- 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(tracker?.malId)
- addAniListId(tracker?.aniId?.toIntOrNull())
- }
- }
-
- override suspend fun loadLinks(
- data: String,
- isCasting: Boolean,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ): Boolean {
-
- val document = request(data).document
-
- document.select(".mobius > .mirror > option").apmap {
- safeApiCall {
- val iframe = fixUrl(
- Jsoup.parse(base64Decode(it.attr("data-em"))).select("iframe").attr("src")
- ?: throw ErrorLoadingException("No iframe found")
- )
- val quality = getIndexQuality(it.text())
- when {
- iframe.startsWith("$mainUrl/utils/player/arch/") || iframe.startsWith(
- "$mainUrl/utils/player/race/"
- ) -> request(iframe, ref = data).document.select("source").attr("src")
- .let { link ->
- val source =
- when {
- iframe.contains("/arch/") -> "Arch"
- iframe.contains("/race/") -> "Race"
- else -> this.name
- }
- callback.invoke(
- ExtractorLink(
- source = source,
- name = source,
- url = link,
- referer = mainUrl,
- quality = quality
- )
- )
- }
-// skip for now
-// 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")
- }"
- loadFixedExtractor(link, quality, mainUrl, subtitleCallback, callback)
- }
- iframe.startsWith("$mainUrl/utils/player/framezilla/") || iframe.startsWith("https://uservideo.xyz") -> {
- request(iframe, ref = data).document.select("iframe").attr("src")
- .let { link ->
- loadFixedExtractor(fixUrl(link), quality, mainUrl, subtitleCallback, callback)
- }
- }
- else -> {
- loadFixedExtractor(iframe, quality, mainUrl, subtitleCallback, callback)
- }
- }
- }
- }
-
- return true
- }
-
- private suspend fun loadFixedExtractor(
- url: String,
- quality: Int?,
- referer: String? = null,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ) {
- loadExtractor(url, referer, subtitleCallback) { link ->
- callback.invoke(
- ExtractorLink(
- link.name,
- link.name,
- link.url,
- link.referer,
- if(link.type == ExtractorLinkType.M3U8) link.quality else quality ?: Qualities.Unknown.value,
- link.type,
- link.headers,
- link.extractorData
- )
- )
- }
- }
-
- private fun getIndexQuality(str: String): Int {
- return Regex("(\\d{3,4})[pP]").find(str)?.groupValues?.getOrNull(1)?.toIntOrNull()
- ?: Qualities.Unknown.value
- }
-
-}
\ No newline at end of file
diff --git a/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProviderPlugin.kt b/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProviderPlugin.kt
deleted file mode 100644
index dfdc4c0c..00000000
--- a/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProviderPlugin.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package com.hexated
-
-import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
-import com.lagradost.cloudstream3.plugins.Plugin
-import android.content.Context
-
-@CloudstreamPlugin
-class AnimeSailProviderPlugin: Plugin() {
- override fun load(context: Context) {
- // All providers should be added in this manner. Please don't edit the providers list directly.
- registerMainAPI(AnimeSailProvider())
- }
-}
\ No newline at end of file
diff --git a/Animixplay/build.gradle.kts b/Animixplay/build.gradle.kts
deleted file mode 100644
index 4d5730fa..00000000
--- a/Animixplay/build.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-// use an integer for version numbers
-version = 7
-
-
-cloudstream {
- language = "en"
- // All of these properties are optional, you can safely remove them
-
- // description = "Lorem Ipsum"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 1 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "Anime",
- "OVA",
- )
-
- iconUrl = "https://www.google.com/s2/favicons?domain=animixplay.to&sz=%size%"
-}
\ No newline at end of file
diff --git a/Animixplay/src/main/AndroidManifest.xml b/Animixplay/src/main/AndroidManifest.xml
deleted file mode 100644
index 874740e3..00000000
--- a/Animixplay/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Animixplay/src/main/kotlin/com/hexated/Animixplay.kt b/Animixplay/src/main/kotlin/com/hexated/Animixplay.kt
deleted file mode 100644
index 79be5f62..00000000
--- a/Animixplay/src/main/kotlin/com/hexated/Animixplay.kt
+++ /dev/null
@@ -1,446 +0,0 @@
-package com.hexated
-
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.hexated.GogoExtractor.extractVidstream
-import com.lagradost.cloudstream3.*
-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
-import org.jsoup.Jsoup
-import java.net.URI
-
-
-class Animixplay : MainAPI() {
- override var mainUrl = "https://animixplay.red"
- override var name = "Animixplay"
- override val hasMainPage = true
- override var lang = "en"
- override val hasQuickSearch = true
- override val hasDownloadSupport = true
-
- override val supportedTypes = setOf(
- TvType.Anime,
- TvType.AnimeMovie,
- TvType.OVA
- )
-
- companion object {
- fun getStatus(t: String?): ShowStatus {
- return when (t) {
- "Finished Airing" -> ShowStatus.Completed
- "Currently Airing" -> ShowStatus.Ongoing
- else -> ShowStatus.Completed
- }
- }
- }
-
- override val mainPage = mainPageOf(
- "$mainUrl/api/search" to "Sub",
- "$mainUrl/api/search" to "Dub",
- "$mainUrl/a/XsWgdGCnKJfNvDFAM28EV" to "All",
- "$mainUrl/api/search" to "Movie",
- )
-
- private var newPagination: String? = null
- override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
- val items = mutableListOf()
- val paged = page.toString()
- val pagination = if (request.name == "Movie") {
- paged.replace(paged, "99999999")
- } else {
- paged.replace(paged, "3020-05-06 00:00:00")
- }
-
- if (page <= 1) {
- val headers = when (request.name) {
- "Sub" -> mapOf("seasonal" to pagination)
- "Dub" -> mapOf("seasonaldub" to pagination)
- "All" -> mapOf("recent" to pagination)
- "Movie" -> mapOf("movie" to pagination)
- else -> mapOf()
- }
- val res = app.post(
- request.data,
- data = headers,
- referer = mainUrl,
- headers = mapOf("X-Requested-With" to "XMLHttpRequest")
- ).parsedSafe()
- newPagination = res?.last.toString()
- val home = res?.result?.mapNotNull {
- it.toSearchResponse()
- } ?: throw ErrorLoadingException("No media found")
- items.add(
- HomePageList(
- name = request.name,
- list = home,
- )
- )
- } else {
- val headers = when (request.name) {
- "Sub" -> mapOf("seasonal" to "$newPagination")
- "Dub" -> mapOf("seasonaldub" to "$newPagination")
- "All" -> mapOf("recent" to "$newPagination")
- "Movie" -> mapOf("movie" to "$newPagination")
- else -> mapOf()
- }
- val res = app.post(
- request.data,
- data = headers,
- referer = mainUrl,
- headers = mapOf("X-Requested-With" to "XMLHttpRequest")
- ).parsedSafe()
- newPagination = res?.last.toString()
- val home = res?.result?.mapNotNull {
- it.toSearchResponse()
- } ?: throw ErrorLoadingException("No media found")
- items.add(
- HomePageList(
- name = request.name,
- list = home,
- )
- )
- }
-
- return newHomePageResponse(items)
- }
-
- private fun Anime.toSearchResponse(): AnimeSearchResponse? {
- return newAnimeSearchResponse(
- title ?: return null,
- fixUrl(url ?: return null),
- TvType.TvSeries,
- ) {
- this.posterUrl = img ?: picture
- addDubStatus(
- isDub = title.contains("Dub"),
- episodes = Regex("EP\\s([0-9]+)/").find(
- infotext ?: ""
- )?.groupValues?.getOrNull(1)
- ?.toIntOrNull()
- )
- }
- }
-
-
- override suspend fun search(query: String): List? {
- return app.post(
- url = "https://v1.ij7p9towl8uj4qafsopjtrjk.workers.dev",
- referer = mainUrl,
- data = mapOf(
- "q2" to query,
- "origin" to "1",
- "root" to "animixplay.to",
- "d" to "gogoanime.tel"
- )
- ).parsedSafe()?.result?.let {
- Jsoup.parse(it).select("div").map { elem ->
-
- val href = fixUrl(elem.select("a").attr("href"))
- val title = elem.select("a").attr("title")
- newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = elem.select("img").attr("src")
- addDubStatus(isDub = title.contains("Dub"))
- }
- }
- }
- }
-
- override suspend fun quickSearch(query: String): List? {
- return app.post(
- "https://cdn.animixplay.to/api/search",
- data = mapOf("qfast" to query, "root" to URI(mainUrl).host)
- ).parsedSafe()?.result?.let {
- Jsoup.parse(it).select("a").map { elem ->
- val href = elem.attr("href")
- val title = elem.select("p.name").text()
- newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = elem.select("img").attr("src")
- addDubStatus(isDub = title.contains("Dub"))
- }
- }
- }
- }
-
- private suspend fun loadMissingAnime(url: String): LoadResponse? {
- val doc = app.get(url).document
-
- val title = doc.selectFirst("span.animetitle")?.text()
- val image = fixUrlNull(doc.selectFirst("meta[property=og:image]")?.attr("content"))
- val genres = doc.selectFirst("span#genredata")?.text()?.split(",")?.map { it.trim() }
-
- val subEpisodes = mutableListOf()
- val dubEpisodes = mutableListOf()
- val dataEps = doc.select("div#epslistplace")
- .text().trim()
- Regex("\"([0-9]+)\":\"(\\S+?)\"").findAll(dataEps).toList()
- .map { it.groupValues[1] to it.groupValues[2] }.map { (ep, link) ->
- val episode = Episode(fixUrl(link), episode = ep.toInt() + 1)
- if (url.contains("-dub")) {
- dubEpisodes.add(episode)
- } else {
- subEpisodes.add(episode)
- }
- }
-
- return newAnimeLoadResponse(
- title ?: return null,
- url,
- TvType.Anime
- ) {
- this.posterUrl = image
- this.tags = genres
- if (subEpisodes.isNotEmpty()) addEpisodes(DubStatus.Subbed, subEpisodes)
- if (dubEpisodes.isNotEmpty()) addEpisodes(DubStatus.Dubbed, dubEpisodes)
- }
- }
-
- override suspend fun load(url: String): LoadResponse? {
-
- val (fixUrl, malId) = if (url.contains("/anime/")) {
- listOf(url, Regex("anime/([0-9]+)/?").find(url)?.groupValues?.get(1))
- } else {
- val malId = app.get(url).text.substringAfterLast("malid = '").substringBefore("';")
- listOf("$mainUrl/anime/$malId", malId)
- }
-
- val anilistId = app.post(
- "https://graphql.anilist.co/", data = mapOf(
- "query" to "{Media(idMal:$malId,type:ANIME){id}}",
- )
- ).parsedSafe()?.data?.media?.id
-
- val res = app.get("$mainUrl/assets/mal/$malId.json").parsedSafe()
- ?: return loadMissingAnime(url)
-
- val subEpisodes = mutableListOf()
- val dubEpisodes = mutableListOf()
-
- app.post("$mainUrl/api/search", data = mapOf("recomended" to "$malId"))
- .parsedSafe()?.data?.map { server ->
- server.items?.apmap { data ->
- val jsonData =
- app.get(
- fixUrl(
- data.url ?: return@apmap null
- )
- ).document.select("div#epslistplace")
- .text().trim()
- val episodeData = when (server.type) {
- "AL" -> Regex("\"([0-9]+)\":\\[(.*?)]").findAll(jsonData).toList()
- .map { it.groupValues[1] to it.groupValues[2] }.map { (ep, link) ->
- Episode(link, episode = ep.toInt() + 1)
- }
- "RUSH" -> Regex("\"([0-9]+)\":\\[(.*?)]").findAll(jsonData).toList()
- .map { it.groupValues[1] to it.groupValues[2] }.map { (ep, link) ->
- val linkData =
- Regex("\"vid\":\"(\\S+?)\"").findAll(link)
- .map { it.groupValues[1] }
- .toList().joinToString("")
- Episode(linkData, episode = ep.toInt() + 1)
- }
- else -> {
- Regex("\"([0-9]+)\":\"(\\S+?)\"").findAll(jsonData).toList()
- .map { it.groupValues[1] to it.groupValues[2] }.map { (ep, link) ->
- Episode(fixUrl(link), episode = ep.toInt() + 1)
- }
- }
- }
- episodeData.map {
- if (data.url.contains("-dub")) {
- dubEpisodes.add(it)
- } else {
- subEpisodes.add(it)
- }
- }
- }
- }
-
- val recommendations = app.get("$mainUrl/assets/similar/$malId.json")
- .parsedSafe()?.recommendations?.mapNotNull { rec ->
- newAnimeSearchResponse(
- rec.title ?: return@mapNotNull null,
- "$mainUrl/anime/${rec.malId}/",
- TvType.Anime
- ) {
- this.posterUrl = rec.imageUrl
- addDubStatus(dubExist = false, subExist = true)
- }
- }
-
- return newAnimeLoadResponse(
- res.title ?: return null,
- url,
- TvType.Anime
- ) {
- engName = res.title
- posterUrl = res.imageUrl
- this.year = res.aired?.from?.split("-")?.firstOrNull()?.toIntOrNull()
- showStatus = getStatus(res.status)
- plot = res.synopsis
- this.tags = res.genres?.mapNotNull { it.name }
- this.recommendations = recommendations
- addMalId(malId?.toIntOrNull())
- addAniListId(anilistId?.toIntOrNull())
- addTrailer(res.trailerUrl)
- if (subEpisodes.isNotEmpty()) addEpisodes(DubStatus.Subbed, groupEpisodes(subEpisodes))
- if (dubEpisodes.isNotEmpty()) addEpisodes(DubStatus.Dubbed, groupEpisodes(dubEpisodes))
- }
-
- }
-
- override suspend fun loadLinks(
- data: String,
- isCasting: Boolean,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ): Boolean {
- if (!data.contains("\"")) {
- invokeGogo(data, subtitleCallback, callback)
- } else {
- data.split("http").apmap {
- val link = it.replace("\"", "").let { url -> "http$url".trim() }
- if (link.startsWith("https://gogohd.net")) {
- invokeGogo(link, subtitleCallback, callback)
- } else {
- loadExtractor(link, "$mainUrl/", subtitleCallback) { links ->
- val name =
- if (link.startsWith("https://streamsb.net")) "StreamNet" else links.name
- callback.invoke(
- ExtractorLink(
- name,
- name,
- links.url,
- links.referer,
- links.quality,
- links.isM3u8,
- links.headers,
- links.extractorData
- )
- )
- }
- }
- }
- }
- return true
- }
-
- private fun groupEpisodes(episodes: List): List {
- return episodes.groupBy { it.episode }.map { eps ->
- val epsNum = eps.key
- val epsLink = eps.value.joinToString("") { it.data }.replace("\",\"", "")
- Episode(epsLink, episode = epsNum)
- }
- }
-
- private suspend fun invokeGogo(
- link: String,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ) {
- val iframe = app.get(link)
- val iframeDoc = iframe.document
- argamap({
- iframeDoc.select(".list-server-items > .linkserver")
- .forEach { element ->
- val status = element.attr("data-status") ?: return@forEach
- if (status != "1") return@forEach
- val extractorData = element.attr("data-video") ?: return@forEach
- loadExtractor(extractorData, iframe.url, subtitleCallback, callback)
- }
- }, {
- val iv = "3134003223491201"
- val secretKey = "37911490979715163134003223491201"
- val secretDecryptKey = "54674138327930866480207815084989"
- extractVidstream(
- iframe.url,
- this.name,
- callback,
- iv,
- secretKey,
- secretDecryptKey,
- isUsingAdaptiveKeys = false,
- isUsingAdaptiveData = true,
- iframeDocument = iframeDoc
- )
- })
- }
-
- 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,
- )
-
- private data class Items(
- @JsonProperty("url") val url: String? = null,
- @JsonProperty("title") val title: String? = null,
- )
-
- private data class Episodes(
- @JsonProperty("type") val type: String? = null,
- @JsonProperty("items") val items: ArrayList? = arrayListOf(),
- )
-
- private data class Data(
- @JsonProperty("data") val data: ArrayList? = arrayListOf(),
- )
-
- private data class Aired(
- @JsonProperty("from") val from: String? = null,
- )
-
- private data class Genres(
- @JsonProperty("name") val name: String? = null,
- )
-
- private data class RecResult(
- @JsonProperty("recommendations") val recommendations: ArrayList? = arrayListOf(),
- )
-
- private data class Recommendations(
- @JsonProperty("mal_id") val malId: String? = null,
- @JsonProperty("image_url") val imageUrl: String? = null,
- @JsonProperty("title") val title: String? = null,
- )
-
- private data class AnimeDetail(
- @JsonProperty("title") val title: String? = null,
- @JsonProperty("image_url") val imageUrl: String? = null,
- @JsonProperty("type") val type: String? = null,
- @JsonProperty("aired") val aired: Aired? = null,
- @JsonProperty("status") val status: String? = null,
- @JsonProperty("synopsis") val synopsis: String? = null,
- @JsonProperty("trailer_url") val trailerUrl: String? = null,
- @JsonProperty("genres") val genres: ArrayList? = arrayListOf(),
- )
-
- private data class Search(
- @JsonProperty("result") val result: String? = null,
- )
-
- private data class Result(
- @JsonProperty("result") val result: ArrayList = arrayListOf(),
- @JsonProperty("last") val last: Any? = null,
- )
-
- private data class Anime(
- @JsonProperty("title") val title: String? = null,
- @JsonProperty("url") val url: String? = null,
- @JsonProperty("img") val img: String? = null,
- @JsonProperty("picture") val picture: String? = null,
- @JsonProperty("infotext") val infotext: String? = null,
- )
-
- private data class FullSearch(
- @JsonProperty("result") val result: String? = null,
- )
-
-}
\ No newline at end of file
diff --git a/Animixplay/src/main/kotlin/com/hexated/AnimixplayPlugin.kt b/Animixplay/src/main/kotlin/com/hexated/AnimixplayPlugin.kt
deleted file mode 100644
index e759a515..00000000
--- a/Animixplay/src/main/kotlin/com/hexated/AnimixplayPlugin.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package com.hexated
-
-import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
-import com.lagradost.cloudstream3.plugins.Plugin
-import android.content.Context
-
-@CloudstreamPlugin
-class AnimixplayPlugin: Plugin() {
- override fun load(context: Context) {
- // All providers should be added in this manner. Please don't edit the providers list directly.
- registerMainAPI(Animixplay())
- }
-}
\ No newline at end of file
diff --git a/Animixplay/src/main/kotlin/com/hexated/GogoExtractor.kt b/Animixplay/src/main/kotlin/com/hexated/GogoExtractor.kt
deleted file mode 100644
index ed19fd25..00000000
--- a/Animixplay/src/main/kotlin/com/hexated/GogoExtractor.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-package com.hexated
-
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.lagradost.cloudstream3.app
-import com.lagradost.cloudstream3.base64Decode
-import com.lagradost.cloudstream3.base64DecodeArray
-import com.lagradost.cloudstream3.base64Encode
-import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
-import com.lagradost.cloudstream3.mvvm.safeApiCall
-import com.lagradost.cloudstream3.utils.AppUtils
-import com.lagradost.cloudstream3.utils.ExtractorLink
-import com.lagradost.cloudstream3.utils.M3u8Helper
-import com.lagradost.cloudstream3.utils.getQualityFromName
-import org.jsoup.nodes.Document
-import java.net.URI
-import javax.crypto.Cipher
-import javax.crypto.spec.IvParameterSpec
-import javax.crypto.spec.SecretKeySpec
-
-object GogoExtractor {
-
- /**
- * @param id base64Decode(show_id) + IV
- * @return the encryption key
- * */
- private fun getKey(id: String): String? {
- return normalSafeApiCall {
- id.map {
- it.code.toString(16)
- }.joinToString("").substring(0, 32)
- }
- }
-
- // https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt#L60
- // No Licence on the function
- private fun cryptoHandler(
- string: String,
- iv: String,
- secretKeyString: String,
- encrypt: Boolean = true
- ): String {
- //println("IV: $iv, Key: $secretKeyString, encrypt: $encrypt, Message: $string")
- val ivParameterSpec = IvParameterSpec(iv.toByteArray())
- val secretKey = SecretKeySpec(secretKeyString.toByteArray(), "AES")
- val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
- return if (!encrypt) {
- cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
- String(cipher.doFinal(base64DecodeArray(string)))
- } else {
- cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
- base64Encode(cipher.doFinal(string.toByteArray()))
- }
- }
-
- /**
- * @param iframeUrl something like https://gogoplay4.com/streaming.php?id=XXXXXX
- * @param mainApiName used for ExtractorLink names and source
- * @param iv secret iv from site, required non-null if isUsingAdaptiveKeys is off
- * @param secretKey secret key for decryption from site, required non-null if isUsingAdaptiveKeys is off
- * @param secretDecryptKey secret key to decrypt the response json, required non-null if isUsingAdaptiveKeys is off
- * @param isUsingAdaptiveKeys generates keys from IV and ID, see getKey()
- * @param isUsingAdaptiveData generate encrypt-ajax data based on $("script[data-name='episode']")[0].dataset.value
- * */
- suspend fun extractVidstream(
- iframeUrl: String,
- mainApiName: String,
- callback: (ExtractorLink) -> Unit,
- iv: String?,
- secretKey: String?,
- secretDecryptKey: String?,
- // This could be removed, but i prefer it verbose
- isUsingAdaptiveKeys: Boolean,
- isUsingAdaptiveData: Boolean,
- // If you don't want to re-fetch the document
- iframeDocument: Document? = null
- ) = safeApiCall {
- // https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt
- // No Licence on the following code
- // Also modified of https://github.com/jmir1/aniyomi-extensions/blob/master/src/en/gogoanime/src/eu/kanade/tachiyomi/animeextension/en/gogoanime/extractors/GogoCdnExtractor.kt
- // License on the code above https://github.com/jmir1/aniyomi-extensions/blob/master/LICENSE
-
- if ((iv == null || secretKey == null || secretDecryptKey == null) && !isUsingAdaptiveKeys)
- return@safeApiCall
-
- val id = Regex("id=([^&]+)").find(iframeUrl)!!.value.removePrefix("id=")
-
- var document: Document? = iframeDocument
- val foundIv =
- iv ?: (document ?: app.get(iframeUrl).document.also { document = it })
- .select("""div.wrapper[class*=container]""")
- .attr("class").split("-").lastOrNull() ?: return@safeApiCall
- val foundKey = secretKey ?: getKey(base64Decode(id) + foundIv) ?: return@safeApiCall
- val foundDecryptKey = secretDecryptKey ?: foundKey
-
- val uri = URI(iframeUrl)
- val mainUrl = "https://" + uri.host
-
- val encryptedId = cryptoHandler(id, foundIv, foundKey)
- val encryptRequestData = if (isUsingAdaptiveData) {
- // Only fetch the document if necessary
- val realDocument = document ?: app.get(iframeUrl).document
- val dataEncrypted =
- realDocument.select("script[data-name='episode']").attr("data-value")
- val headers = cryptoHandler(dataEncrypted, foundIv, foundKey, false)
- "id=$encryptedId&alias=$id&" + headers.substringAfter("&")
- } else {
- "id=$encryptedId&alias=$id"
- }
-
- val jsonResponse =
- app.get(
- "$mainUrl/encrypt-ajax.php?$encryptRequestData",
- headers = mapOf("X-Requested-With" to "XMLHttpRequest")
- )
- val dataencrypted =
- jsonResponse.text.substringAfter("{\"data\":\"").substringBefore("\"}")
- val datadecrypted = cryptoHandler(dataencrypted, foundIv, foundDecryptKey, false)
- val sources = AppUtils.parseJson(datadecrypted)
-
- suspend fun invokeGogoSource(
- source: GogoSource,
- sourceCallback: (ExtractorLink) -> Unit
- ) {
- if (source.file.contains(".m3u8")) {
- M3u8Helper.generateM3u8(
- mainApiName,
- source.file,
- mainUrl,
- headers = mapOf("Origin" to "https://plyr.link")
- ).forEach(sourceCallback)
- } else {
- sourceCallback.invoke(
- ExtractorLink(
- mainApiName,
- mainApiName,
- source.file,
- mainUrl,
- getQualityFromName(source.label),
- )
- )
- }
- }
-
- sources.source?.forEach {
- invokeGogoSource(it, callback)
- }
- sources.sourceBk?.forEach {
- invokeGogoSource(it, callback)
- }
- }
-
- data class GogoSources(
- @JsonProperty("source") val source: List?,
- @JsonProperty("sourceBk") val sourceBk: List?,
- //val track: List,
- //val advertising: List,
- //val linkiframe: String
- )
-
- data class GogoSource(
- @JsonProperty("file") val file: String,
- @JsonProperty("label") val label: String?,
- @JsonProperty("type") val type: String?,
- @JsonProperty("default") val default: String? = null
- )
-}
diff --git a/Aniworld/build.gradle.kts b/Aniworld/build.gradle.kts
deleted file mode 100644
index 86c61272..00000000
--- a/Aniworld/build.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-// use an integer for version numbers
-version = 6
-
-
-cloudstream {
- language = "de"
- // All of these properties are optional, you can safely remove them
-
- description = "Include: Serienstream"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 1 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "Anime",
- "OVA",
- )
-
- iconUrl = "https://www.google.com/s2/favicons?domain=aniworld.to&sz=%size%"
-}
\ No newline at end of file
diff --git a/Aniworld/src/main/AndroidManifest.xml b/Aniworld/src/main/AndroidManifest.xml
deleted file mode 100644
index c98063f8..00000000
--- a/Aniworld/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt b/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt
deleted file mode 100644
index 1fb28346..00000000
--- a/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt
+++ /dev/null
@@ -1,189 +0,0 @@
-package com.hexated
-
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.lagradost.cloudstream3.*
-import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
-import com.lagradost.cloudstream3.extractors.DoodLaExtractor
-import com.lagradost.cloudstream3.extractors.Voe
-import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
-import com.lagradost.cloudstream3.utils.ExtractorLink
-import com.lagradost.cloudstream3.utils.loadExtractor
-import org.jsoup.nodes.Document
-import org.jsoup.nodes.Element
-
-open class Aniworld : MainAPI() {
- override var mainUrl = "https://aniworld.to"
- override var name = "Aniworld"
- override val hasMainPage = true
- override var lang = "de"
-
- override val supportedTypes = setOf(
- TvType.Anime,
- TvType.AnimeMovie,
- TvType.OVA
- )
-
- override suspend fun getMainPage(
- page: Int,
- request: MainPageRequest
- ): HomePageResponse {
-
- val document = app.get(mainUrl).document
- val item = arrayListOf()
- document.select("div.carousel").map { ele ->
- val header = ele.selectFirst("h2")?.text() ?: return@map
- val home = ele.select("div.coverListItem").mapNotNull {
- it.toSearchResult()
- }
- if (home.isNotEmpty()) item.add(HomePageList(header, home))
- }
- return HomePageResponse(item)
- }
-
- override suspend fun search(query: String): List {
- val json = app.post(
- "$mainUrl/ajax/search",
- data = mapOf("keyword" to query),
- referer = "$mainUrl/search",
- headers = mapOf(
- "x-requested-with" to "XMLHttpRequest"
- )
- )
- return tryParseJson>(json.text)?.filter {
- !it.link.contains("episode-") && it.link.contains(
- "/stream"
- )
- }?.map {
- newAnimeSearchResponse(
- it.title?.replace(Regex("?em>"), "") ?: "",
- fixUrl(it.link),
- TvType.Anime
- ) {
- }
- } ?: throw ErrorLoadingException()
-
- }
-
- override suspend fun load(url: String): LoadResponse? {
- val document = app.get(url).document
-
- val title = document.selectFirst("div.series-title span")?.text() ?: return null
- val poster = fixUrlNull(document.selectFirst("div.seriesCoverBox img")?.attr("data-src"))
- val tags = document.select("div.genres li a").map { it.text() }
- val year = document.selectFirst("span[itemprop=startDate] a")?.text()?.toIntOrNull()
- val description = document.select("p.seri_des").text()
- val actor =
- document.select("li:contains(Schauspieler:) ul li a").map { it.select("span").text() }
-
- val episodes = mutableListOf()
- document.select("div#stream > ul:first-child li").map { ele ->
- val page = ele.selectFirst("a")
- val epsDocument = app.get(fixUrl(page?.attr("href") ?: return@map)).document
- epsDocument.select("div#stream > ul:nth-child(4) li").mapNotNull { eps ->
- episodes.add(
- Episode(
- fixUrl(eps.selectFirst("a")?.attr("href") ?: return@mapNotNull null),
- episode = eps.selectFirst("a")?.text()?.toIntOrNull(),
- season = page.text().toIntOrNull()
- )
- )
- }
- }
-
- return newAnimeLoadResponse(
- title,
- url,
- TvType.Anime
- ) {
- engName = title
- posterUrl = poster
- this.year = year
- addEpisodes(
- DubStatus.Subbed,
- episodes
- )
- addActors(actor)
- plot = description
- this.tags = tags
- }
- }
-
- override suspend fun loadLinks(
- data: String,
- isCasting: Boolean,
- subtitleCallback: (SubtitleFile) -> Unit,
- callback: (ExtractorLink) -> Unit
- ): Boolean {
- val document = app.get(data).document
- document.select("div.hosterSiteVideo ul li").map {
- Triple(
- it.attr("data-lang-key"),
- it.attr("data-link-target"),
- it.select("h4").text()
- )
- }.filter {
- it.third != "Vidoza"
- }.apmap {
- val redirectUrl = app.get(fixUrl(it.second)).url
- val lang = it.first.getLanguage(document)
- val name = "${it.third} [${lang}]"
- if (it.third == "VOE") {
- Voe().getUrl(redirectUrl, data, subtitleCallback) { link ->
- callback.invoke(
- ExtractorLink(
- name,
- name,
- link.url,
- link.referer,
- link.quality,
- link.type,
- link.headers,
- link.extractorData
- )
- )
- }
- } else {
- loadExtractor(redirectUrl, data, subtitleCallback) { link ->
- callback.invoke(
- ExtractorLink(
- name,
- name,
- link.url,
- link.referer,
- link.quality,
- link.type,
- link.headers,
- link.extractorData
- )
- )
- }
- }
- }
-
- return true
- }
-
- private fun Element.toSearchResult(): AnimeSearchResponse? {
- val href = fixUrlNull(this.selectFirst("a")?.attr("href")) ?: return null
- val title = this.selectFirst("h3")?.text() ?: return null
- val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("data-src"))
- return newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = posterUrl
- }
- }
-
- private fun String.getLanguage(document: Document): String? {
- return document.selectFirst("div.changeLanguageBox img[data-lang-key=$this]")?.attr("title")
- ?.removePrefix("mit")?.trim()
- }
-
- private data class AnimeSearch(
- @JsonProperty("link") val link: String,
- @JsonProperty("title") val title: String? = null,
- )
-
-}
-
-class Dooood : DoodLaExtractor() {
- override var mainUrl = "https://urochsunloath.com"
-}
\ No newline at end of file
diff --git a/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt b/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt
deleted file mode 100644
index 3e86596b..00000000
--- a/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-
-package com.hexated
-
-import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
-import com.lagradost.cloudstream3.plugins.Plugin
-import android.content.Context
-
-@CloudstreamPlugin
-class AniworldPlugin: Plugin() {
- override fun load(context: Context) {
- // All providers should be added in this manner. Please don't edit the providers list directly.
- registerMainAPI(Aniworld())
- registerMainAPI(Serienstream())
- registerExtractorAPI(Dooood())
- }
-}
\ No newline at end of file
diff --git a/Aniworld/src/main/kotlin/com/hexated/Serienstream.kt b/Aniworld/src/main/kotlin/com/hexated/Serienstream.kt
deleted file mode 100644
index ff475aa6..00000000
--- a/Aniworld/src/main/kotlin/com/hexated/Serienstream.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.hexated
-
-import com.lagradost.cloudstream3.LoadResponse
-import com.lagradost.cloudstream3.TvType
-
-class Serienstream : Aniworld() {
- override var mainUrl = "https://s.to"
- override var name = "Serienstream"
- override val supportedTypes = setOf(
- TvType.Movie,
- TvType.TvSeries,
- )
-
- override suspend fun load(url: String): LoadResponse? {
- return super.load(url).apply { this?.type = TvType.TvSeries }
- }
-}
\ No newline at end of file
diff --git a/Anizm/build.gradle.kts b/Anizm/build.gradle.kts
deleted file mode 100644
index 618896c5..00000000
--- a/Anizm/build.gradle.kts
+++ /dev/null
@@ -1,27 +0,0 @@
-// use an integer for version numbers
-version = 1
-
-
-cloudstream {
- language = "tr"
- // All of these properties are optional, you can safely remove them
-
- // description = "Lorem Ipsum"
- authors = listOf("Hexated")
-
- /**
- * Status int as the following:
- * 0: Down
- * 1: Ok
- * 2: Slow
- * 3: Beta only
- * */
- status = 0 // will be 3 if unspecified
- tvTypes = listOf(
- "AnimeMovie",
- "Anime",
- "OVA",
- )
-
- iconUrl = "https://www.google.com/s2/favicons?domain=anizm.net&sz=%size%"
-}
\ No newline at end of file
diff --git a/Anizm/src/main/AndroidManifest.xml b/Anizm/src/main/AndroidManifest.xml
deleted file mode 100644
index 874740e3..00000000
--- a/Anizm/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Anizm/src/main/kotlin/com/hexated/Anizm.kt b/Anizm/src/main/kotlin/com/hexated/Anizm.kt
deleted file mode 100644
index 1d5fb8c0..00000000
--- a/Anizm/src/main/kotlin/com/hexated/Anizm.kt
+++ /dev/null
@@ -1,195 +0,0 @@
-package com.hexated
-
-import android.util.Log
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.lagradost.cloudstream3.*
-import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
-import com.lagradost.cloudstream3.mvvm.safeApiCall
-import com.lagradost.cloudstream3.utils.*
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Element
-
-
-class Anizm : MainAPI() {
- override var mainUrl = "https://anizm.net"
- override var name = "Anizm"
- override val hasMainPage = true
- override var lang = "tr"
- override val hasDownloadSupport = true
-
- override val supportedTypes = setOf(
- TvType.Anime,
- TvType.AnimeMovie,
- TvType.OVA
- )
-
- companion object {
- private const val mainServer = "https://anizmplayer.com"
- }
-
- override val mainPage = mainPageOf(
- "$mainUrl/anime-izle?sayfa=" to "Son Eklenen Animeler",
- )
-
- override suspend fun getMainPage(
- page: Int,
- request: MainPageRequest
- ): HomePageResponse {
- val document = app.get(request.data + page).document
- val home = document.select("div.restrictedWidth div#episodesMiddle").mapNotNull {
- it.toSearchResult()
- }
- return newHomePageResponse(request.name, home)
- }
-
- private fun getProperAnimeLink(uri: String): String {
- return if (uri.contains("-bolum")) {
- "$mainUrl/${uri.substringAfter("$mainUrl/").replace(Regex("-[0-9]+-bolum.*"), "")}"
- } else {
- uri
- }
- }
-
- private fun Element.toSearchResult(): AnimeSearchResponse? {
- val href = getProperAnimeLink(this.selectFirst("a")!!.attr("href"))
- val title = this.selectFirst("div.title, h5.animeTitle a")?.text() ?: return null
- val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("src"))
- val episode = this.selectFirst("div.truncateText")?.text()?.let {
- Regex("([0-9]+).\\s?Bölüm").find(it)?.groupValues?.getOrNull(1)?.toIntOrNull()
- }
-
- return newAnimeSearchResponse(title, href, TvType.Anime) {
- this.posterUrl = posterUrl
- addSub(episode)
- }
- }
-
- override suspend fun search(query: String): List {
- val document = app.get(
- "$mainUrl/fullViewSearch?search=$query&skip=0",
- headers = mapOf("X-Requested-With" to "XMLHttpRequest")
- ).document
-
- return document.select("div.searchResultItem").mapNotNull {
- it.toSearchResult()
- }
- }
-
- override suspend fun load(url: String): LoadResponse {
- val document = app.get(url).document
-
- val title = document.selectFirst("h2.anizm_pageTitle a")!!.text().trim()
- val type =
- if (document.select("div.ui.grid div.four.wide").size == 1) TvType.Movie else TvType.Anime
- val trailer = document.select("div.yt-hd-thumbnail-inner-container iframe").attr("src")
- val episodes = document.select("div.ui.grid div.four.wide").map {
- val name = it.select("div.episodeBlock").text()
- val link = fixUrl(it.selectFirst("a")?.attr("href").toString())
- Episode(link, name)
- }
- return newAnimeLoadResponse(title, url, type) {
- posterUrl = fixUrlNull(document.selectFirst("div.infoPosterImg > img")?.attr("src"))
- this.year = document.select("div.infoSta ul li:first-child").text().trim().toIntOrNull()
- addEpisodes(DubStatus.Subbed, episodes)
- plot = document.select("div.infoDesc").text().trim()
- this.tags = document.select("span.dataValue span.ui.label").map { it.text() }
- addTrailer(trailer)
- }
- }
-
- private suspend fun invokeLokalSource(
- url: String,
- translator: String,
- sourceCallback: (ExtractorLink) -> Unit
- ) {
- app.get(url, referer = "$mainUrl/").document.select("script").find { script ->
- script.data().contains("eval(function(p,a,c,k,e,d)")
- }?.let {
- val key = getAndUnpack(it.data()).substringAfter("FirePlayer(\"").substringBefore("\",")
- val referer = "$mainServer/video/$key"
- val link = "$mainServer/player/index.php?data=$key&do=getVideo"
- Log.i("hexated", link)
- app.post(
- link,
- data = mapOf("hash" to key, "r" to "$mainUrl/"),
- referer = referer,
- headers = mapOf(
- "Accept" to "*/*",
- "Origin" to mainServer,
- "Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
- "X-Requested-With" to "XMLHttpRequest"
- )
- ).parsedSafe