mirror of
https://github.com/recloudstream/cloudstream-extensions-multilingual.git
synced 2024-08-15 03:15:14 +00:00
Add anime providers
This commit is contained in:
parent
b74b8614db
commit
b3f33b368a
139 changed files with 9873 additions and 9 deletions
22
AnimeflvIOProvider/build.gradle.kts
Normal file
22
AnimeflvIOProvider/build.gradle.kts
Normal file
|
@ -0,0 +1,22 @@
|
|||
// use an integer for version numbers
|
||||
version = 1
|
||||
|
||||
|
||||
cloudstream {
|
||||
// All of these properties are optional, you can safely remove them
|
||||
|
||||
// description = "Lorem Ipsum"
|
||||
// authors = listOf("Cloudburst")
|
||||
|
||||
/**
|
||||
* Status int as the following:
|
||||
* 0: Down
|
||||
* 1: Ok
|
||||
* 2: Slow
|
||||
* 3: Beta only
|
||||
* */
|
||||
status = 1 // will be 3 if unspecified
|
||||
|
||||
// Set to true to get an 18+ symbol next to the plugin
|
||||
adult = false // will be false if unspecified
|
||||
}
|
2
AnimeflvIOProvider/src/main/AndroidManifest.xml
Normal file
2
AnimeflvIOProvider/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.lagradost"/>
|
|
@ -0,0 +1,239 @@
|
|||
package com.lagradost
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||
import java.util.*
|
||||
|
||||
class AnimeflvIOProvider : MainAPI() {
|
||||
override var mainUrl = "https://animeflv.io" //Also scrapes from animeid.to
|
||||
override var name = "Animeflv.io"
|
||||
override var lang = "es"
|
||||
override val hasMainPage = true
|
||||
override val hasChromecastSupport = true
|
||||
override val hasDownloadSupport = true
|
||||
override val supportedTypes = setOf(
|
||||
TvType.AnimeMovie,
|
||||
TvType.OVA,
|
||||
TvType.Anime,
|
||||
)
|
||||
|
||||
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
|
||||
val items = ArrayList<HomePageList>()
|
||||
val urls = listOf(
|
||||
Pair("$mainUrl/series", "Series actualizadas"),
|
||||
Pair("$mainUrl/peliculas", "Peliculas actualizadas"),
|
||||
)
|
||||
items.add(
|
||||
HomePageList(
|
||||
"Estrenos",
|
||||
app.get(mainUrl).document.select("div#owl-demo-premiere-movies .pull-left").map {
|
||||
val title = it.selectFirst("p")?.text() ?: ""
|
||||
AnimeSearchResponse(
|
||||
title,
|
||||
fixUrl(it.selectFirst("a")?.attr("href") ?: ""),
|
||||
this.name,
|
||||
TvType.Anime,
|
||||
it.selectFirst("img")?.attr("src"),
|
||||
it.selectFirst("span.year").toString().toIntOrNull(),
|
||||
EnumSet.of(DubStatus.Subbed),
|
||||
)
|
||||
})
|
||||
)
|
||||
urls.apmap { (url, name) ->
|
||||
val soup = app.get(url).document
|
||||
val home = soup.select("div.item-pelicula").map {
|
||||
val title = it.selectFirst(".item-detail p")?.text() ?: ""
|
||||
val poster = it.selectFirst("figure img")?.attr("src")
|
||||
AnimeSearchResponse(
|
||||
title,
|
||||
fixUrl(it.selectFirst("a")?.attr("href") ?: ""),
|
||||
this.name,
|
||||
TvType.Anime,
|
||||
poster,
|
||||
null,
|
||||
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
|
||||
DubStatus.Dubbed
|
||||
) else EnumSet.of(DubStatus.Subbed),
|
||||
)
|
||||
}
|
||||
|
||||
items.add(HomePageList(name, home))
|
||||
}
|
||||
|
||||
if (items.size <= 0) throw ErrorLoadingException()
|
||||
return HomePageResponse(items)
|
||||
}
|
||||
|
||||
override suspend fun search(query: String): List<SearchResponse> {
|
||||
val headers = mapOf(
|
||||
"Host" to "animeflv.io",
|
||||
"User-Agent" to USER_AGENT,
|
||||
"X-Requested-With" to "XMLHttpRequest",
|
||||
"DNT" to "1",
|
||||
"Alt-Used" to "animeflv.io",
|
||||
"Connection" to "keep-alive",
|
||||
"Referer" to "https://animeflv.io",
|
||||
)
|
||||
val url = "$mainUrl/search.html?keyword=$query"
|
||||
val document = app.get(
|
||||
url,
|
||||
headers = headers
|
||||
).document
|
||||
return document.select(".item-pelicula.pull-left").map {
|
||||
val title = it.selectFirst("div.item-detail p")?.text() ?: ""
|
||||
val href = fixUrl(it.selectFirst("a")?.attr("href") ?: "")
|
||||
var image = it.selectFirst("figure img")?.attr("src") ?: ""
|
||||
val isMovie = href.contains("/pelicula/")
|
||||
if (image.contains("/static/img/picture.png")) {
|
||||
image = ""
|
||||
}
|
||||
if (isMovie) {
|
||||
MovieSearchResponse(
|
||||
title,
|
||||
href,
|
||||
this.name,
|
||||
TvType.AnimeMovie,
|
||||
image,
|
||||
null
|
||||
)
|
||||
} else {
|
||||
AnimeSearchResponse(
|
||||
title,
|
||||
href,
|
||||
this.name,
|
||||
TvType.Anime,
|
||||
image,
|
||||
null,
|
||||
EnumSet.of(DubStatus.Subbed),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun load(url: String): LoadResponse? {
|
||||
// Gets the url returned from searching.
|
||||
val soup = app.get(url).document
|
||||
val title = soup.selectFirst(".info-content h1")?.text()
|
||||
val description = soup.selectFirst("span.sinopsis")?.text()?.trim()
|
||||
val poster: String? = soup.selectFirst(".poster img")?.attr("src")
|
||||
val episodes = soup.select(".item-season-episodes a").map { li ->
|
||||
val href = fixUrl(li.selectFirst("a")?.attr("href") ?: "")
|
||||
val name = li.selectFirst("a")?.text() ?: ""
|
||||
Episode(
|
||||
href, name,
|
||||
)
|
||||
}.reversed()
|
||||
|
||||
val year = Regex("(\\d*)").find(soup.select(".info-half").text())
|
||||
|
||||
val tvType = if (url.contains("/pelicula/")) TvType.AnimeMovie else TvType.Anime
|
||||
val genre = soup.select(".content-type-a a")
|
||||
.map { it?.text()?.trim().toString().replace(", ", "") }
|
||||
val duration = Regex("""(\d*)""").find(
|
||||
soup.select("p.info-half:nth-child(4)").text()
|
||||
)
|
||||
|
||||
return when (tvType) {
|
||||
TvType.Anime -> {
|
||||
return newAnimeLoadResponse(title ?: "", url, tvType) {
|
||||
japName = null
|
||||
engName = title
|
||||
posterUrl = poster
|
||||
this.year = null
|
||||
addEpisodes(DubStatus.Subbed, episodes)
|
||||
plot = description
|
||||
tags = genre
|
||||
|
||||
showStatus = null
|
||||
}
|
||||
}
|
||||
TvType.AnimeMovie -> {
|
||||
MovieLoadResponse(
|
||||
title ?: "",
|
||||
url,
|
||||
this.name,
|
||||
tvType,
|
||||
url,
|
||||
poster,
|
||||
year.toString().toIntOrNull(),
|
||||
description,
|
||||
null,
|
||||
genre,
|
||||
duration.toString().toIntOrNull(),
|
||||
)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
data class MainJson(
|
||||
@JsonProperty("source") val source: List<Source>,
|
||||
@JsonProperty("source_bk") val sourceBk: String?,
|
||||
@JsonProperty("track") val track: List<String>?,
|
||||
@JsonProperty("advertising") val advertising: List<String>?,
|
||||
@JsonProperty("linkiframe") val linkiframe: String?
|
||||
)
|
||||
|
||||
data class Source(
|
||||
@JsonProperty("file") val file: String,
|
||||
@JsonProperty("label") val label: String,
|
||||
@JsonProperty("default") val default: String,
|
||||
@JsonProperty("type") val type: String
|
||||
)
|
||||
|
||||
override suspend fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
app.get(data).document.select("li.tab-video").apmap {
|
||||
val url = fixUrl(it.attr("data-video"))
|
||||
if (url.contains("animeid")) {
|
||||
val ajaxurl = url.replace("streaming.php", "ajax.php")
|
||||
val ajaxurltext = app.get(ajaxurl).text
|
||||
val json = parseJson<MainJson>(ajaxurltext)
|
||||
json.source.forEach { source ->
|
||||
if (source.file.contains("m3u8")) {
|
||||
generateM3u8(
|
||||
"Animeflv.io",
|
||||
source.file,
|
||||
"https://animeid.to",
|
||||
headers = mapOf("Referer" to "https://animeid.to")
|
||||
).apmap {
|
||||
callback(
|
||||
ExtractorLink(
|
||||
"Animeflv.io",
|
||||
"Animeflv.io",
|
||||
it.url,
|
||||
"https://animeid.to",
|
||||
getQualityFromName(it.quality.toString()),
|
||||
it.url.contains("m3u8")
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
callback(
|
||||
ExtractorLink(
|
||||
name,
|
||||
"$name ${source.label}",
|
||||
source.file,
|
||||
"https://animeid.to",
|
||||
Qualities.Unknown.value,
|
||||
isM3u8 = source.file.contains("m3u8")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
loadExtractor(url, data, subtitleCallback, callback)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
package com.lagradost
|
||||
|
||||
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
|
||||
import com.lagradost.cloudstream3.plugins.Plugin
|
||||
import android.content.Context
|
||||
|
||||
@CloudstreamPlugin
|
||||
class AnimeflvIOProviderPlugin: Plugin() {
|
||||
override fun load(context: Context) {
|
||||
// All providers should be added in this manner. Please don't edit the providers list directly.
|
||||
registerMainAPI(AnimeflvIOProvider())
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue