mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
sora: added Animetosho
This commit is contained in:
parent
3d60b9c792
commit
83e2c399f6
5 changed files with 100 additions and 70 deletions
|
@ -1,7 +1,7 @@
|
|||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
|
||||
// use an integer for version numbers
|
||||
version = 158
|
||||
version = 159
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
|
|
|
@ -17,6 +17,7 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
|||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.select.Elements
|
||||
|
||||
val session = Session(Requests().baseClient)
|
||||
|
||||
|
@ -968,10 +969,10 @@ object SoraExtractor : SoraStream() {
|
|||
|
||||
argamap(
|
||||
{
|
||||
invokeAniwatch(malId, episode, subtitleCallback, callback)
|
||||
invokeAnimetosho(malId, season, episode, subtitleCallback, callback)
|
||||
},
|
||||
{
|
||||
invokeBiliBili(aniId, episode, subtitleCallback, callback)
|
||||
invokeAniwatch(malId, episode, subtitleCallback, callback)
|
||||
},
|
||||
{
|
||||
if (season != null) invokeCrunchyroll(
|
||||
|
@ -987,54 +988,55 @@ object SoraExtractor : SoraStream() {
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun invokeBiliBili(
|
||||
aniId: Int? = null,
|
||||
private suspend fun invokeAnimetosho(
|
||||
malId: Int? = null,
|
||||
season: Int? = null,
|
||||
episode: Int? = null,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val res = app.get(
|
||||
"$biliBiliAPI/anime/episodes?id=${aniId ?: return}&source_id=bilibili",
|
||||
referer = otakuzBaseUrl
|
||||
fun Elements.getLinks(): List<Triple<String, String, Int>> {
|
||||
return this.flatMap { ele ->
|
||||
ele.select("div.links a:matches(KrakenFiles|GoFile)").map {
|
||||
Triple(
|
||||
it.attr("href"),
|
||||
ele.select("div.size").text(),
|
||||
getIndexQuality(ele.select("div.link a").text())
|
||||
)
|
||||
.parsedSafe<BiliBiliDetails>()?.episodes?.find {
|
||||
it.episodeNumber == episode
|
||||
} ?: return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val sources =
|
||||
app.get(
|
||||
"$biliBiliAPI/source?episode_id=${res.sourceEpisodeId}&source_media_id=${res.sourceMediaId}&source_id=${res.sourceId}",
|
||||
referer = otakuzBaseUrl
|
||||
)
|
||||
.parsedSafe<BiliBiliSourcesResponse>()
|
||||
val (seasonSLug, episodeSlug) = getEpisodeSlug(season, episode)
|
||||
val jikan = app.get("$jikanAPI/anime/$malId/full").parsedSafe<JikanResponse>()?.data
|
||||
val aniId = jikan?.external?.find { it.name == "AniDB" }?.url?.substringAfterLast("=")
|
||||
val res = app.get("$animetoshoAPI/series/${jikan?.title?.createSlug()}.$aniId?filter[0][t]=nyaa_class&filter[0][v]=trusted").document
|
||||
|
||||
sources?.sources?.apmap { source ->
|
||||
val quality =
|
||||
app.get(
|
||||
source.file ?: return@apmap null,
|
||||
referer = otakuzBaseUrl
|
||||
).document.selectFirst("Representation")
|
||||
?.attr("height")
|
||||
val servers = if (season == null) {
|
||||
res.select("div.home_list_entry:has(div.links)").getLinks()
|
||||
} else {
|
||||
res.select("div.home_list_entry:has(div.link a:matches([\\.\\s]$episodeSlug[\\.\\s]|S${seasonSLug}E$episodeSlug))")
|
||||
.getLinks()
|
||||
}
|
||||
|
||||
servers.filter { it.third in arrayOf(Qualities.P1080.value,Qualities.P720.value) }.apmap {
|
||||
loadExtractor(it.first, "$animetoshoAPI/", subtitleCallback) { link ->
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
"BiliBili",
|
||||
"BiliBili",
|
||||
source.file,
|
||||
"",
|
||||
quality?.toIntOrNull() ?: Qualities.Unknown.value,
|
||||
isDash = true
|
||||
link.source,
|
||||
"${link.name} [${it.second}]",
|
||||
link.url,
|
||||
link.referer,
|
||||
when {
|
||||
link.isM3u8 -> link.quality
|
||||
else -> it.third
|
||||
},
|
||||
link.isM3u8,
|
||||
link.headers,
|
||||
link.extractorData
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
sources?.subtitles?.map { sub ->
|
||||
subtitleCallback.invoke(
|
||||
SubtitleFile(
|
||||
SubtitleHelper.fromTwoLettersToLanguage(sub.lang ?: "") ?: sub.language
|
||||
?: return@map null,
|
||||
sub.file ?: return@map null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2209,7 +2211,7 @@ object SoraExtractor : SoraStream() {
|
|||
"$dahmerMoviesAPI/tvs/${title?.replace(":", " -")}/Season $season/"
|
||||
}
|
||||
|
||||
val request = app.get(url)
|
||||
val request = app.get(url, timeout = 120L)
|
||||
if (!request.isSuccessful) return
|
||||
val paths = request.document.select("a").map {
|
||||
it.text() to it.attr("href")
|
||||
|
@ -2239,6 +2241,33 @@ object SoraExtractor : SoraStream() {
|
|||
|
||||
}
|
||||
|
||||
suspend fun invoke2embed(
|
||||
imdbId: String?,
|
||||
season: Int?,
|
||||
episode: Int?,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val server = "https://stream.2embed.cc"
|
||||
val url = if(season == null) {
|
||||
"$twoEmbedAPI/embed/$imdbId"
|
||||
} else {
|
||||
"$twoEmbedAPI/embedtv/$imdbId&s=$season&e=$episode"
|
||||
}
|
||||
|
||||
val iframesrc = app.get(url).document.selectFirst("iframe#iframesrc")?.attr("src")
|
||||
val framesrc = app.get(fixUrl(iframesrc ?: return, twoEmbedAPI)).document.selectFirst("iframe#framesrc")?.attr("src")
|
||||
val video = app.get(fixUrl(framesrc ?: return, "$server/e/")).text.let {
|
||||
Regex("file:\\s*\"(.*?m3u8.*?)\"").find(it)?.groupValues?.getOrNull(1)
|
||||
}
|
||||
|
||||
M3u8Helper.generateM3u8(
|
||||
"2embed",
|
||||
video ?: return,
|
||||
"$server/",
|
||||
).forEach(callback)
|
||||
|
||||
}
|
||||
|
||||
suspend fun invokePrimewire(
|
||||
title: String? = null,
|
||||
year: Int? = null,
|
||||
|
|
|
@ -177,32 +177,18 @@ data class IndexSearch(
|
|||
@JsonProperty("data") val data: IndexData? = null,
|
||||
)
|
||||
|
||||
data class BiliBiliEpisodes(
|
||||
@JsonProperty("id") val id: Int? = null,
|
||||
@JsonProperty("sourceId") val sourceId: String? = null,
|
||||
@JsonProperty("sourceEpisodeId") val sourceEpisodeId: String? = null,
|
||||
@JsonProperty("sourceMediaId") val sourceMediaId: String? = null,
|
||||
@JsonProperty("episodeNumber") val episodeNumber: Int? = null,
|
||||
data class JikanExternal(
|
||||
@JsonProperty("name") val name: String? = null,
|
||||
@JsonProperty("url") val url: String? = null,
|
||||
)
|
||||
|
||||
data class BiliBiliDetails(
|
||||
@JsonProperty("episodes") val episodes: ArrayList<BiliBiliEpisodes>? = arrayListOf(),
|
||||
data class JikanData(
|
||||
@JsonProperty("title") val title: String? = null,
|
||||
@JsonProperty("external") val external: ArrayList<JikanExternal>? = arrayListOf(),
|
||||
)
|
||||
|
||||
data class BiliBiliSubtitles(
|
||||
@JsonProperty("file") val file: String? = null,
|
||||
@JsonProperty("lang") val lang: String? = null,
|
||||
@JsonProperty("language") val language: String? = null,
|
||||
)
|
||||
|
||||
data class BiliBiliSources(
|
||||
@JsonProperty("file") val file: String? = null,
|
||||
@JsonProperty("type") val type: String? = null,
|
||||
)
|
||||
|
||||
data class BiliBiliSourcesResponse(
|
||||
@JsonProperty("sources") val sources: ArrayList<BiliBiliSources>? = arrayListOf(),
|
||||
@JsonProperty("subtitles") val subtitles: ArrayList<BiliBiliSubtitles>? = arrayListOf(),
|
||||
data class JikanResponse(
|
||||
@JsonProperty("data") val data: JikanData? = null,
|
||||
)
|
||||
|
||||
data class WatchOnlineItems(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.hexated
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.hexated.SoraExtractor.invoke2embed
|
||||
import com.hexated.SoraExtractor.invokeAnimes
|
||||
import com.hexated.SoraExtractor.invokeAsk4Movies
|
||||
import com.hexated.SoraExtractor.invokeBollyMaza
|
||||
|
@ -80,11 +81,13 @@ open class SoraStream : TmdbProvider() {
|
|||
const val anilistAPI = "https://graphql.anilist.co"
|
||||
const val malsyncAPI = "https://api.malsync.moe"
|
||||
const val consumetHelper = "https://api.consumet.org/anime/9anime/helper"
|
||||
const val jikanAPI = "https://api.jikan.moe/v4"
|
||||
|
||||
private val apiKey =
|
||||
base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL
|
||||
|
||||
/** ALL SOURCES */
|
||||
const val twoEmbedAPI = "https://www.2embed.cc"
|
||||
const val vidSrcAPI = "https://v2.vidsrc.me"
|
||||
const val dbgoAPI = "https://dbgo.fun"
|
||||
const val movieHabAPI = "https://moviehab.com"
|
||||
|
@ -113,7 +116,6 @@ open class SoraStream : TmdbProvider() {
|
|||
const val smashyStreamAPI = "https://embed.smashystream.com"
|
||||
const val watchSomuchAPI = "https://watchsomuch.tv" // sub only
|
||||
const val ask4MoviesAPI = "https://ask4movie.nl"
|
||||
const val biliBiliAPI = "https://api-vn.otakuz.live/server"
|
||||
const val watchOnlineAPI = "https://watchonline.ag"
|
||||
const val nineTvAPI = "https://moviesapi.club"
|
||||
const val putlockerAPI = "https://ww7.putlocker.vip"
|
||||
|
@ -132,6 +134,7 @@ open class SoraStream : TmdbProvider() {
|
|||
const val primewireAPI = "https://real-primewire.club"
|
||||
const val vidsrctoAPI = "https://vidsrc.to"
|
||||
const val dramadayAPI = "https://dramaday.me"
|
||||
const val animetoshoAPI = "https://animetosho.org"
|
||||
|
||||
// INDEX SITE
|
||||
const val dahmerMoviesAPI = "https://edytjedhgmdhm.abfhaqrhbnf.workers.dev"
|
||||
|
@ -739,7 +742,10 @@ open class SoraStream : TmdbProvider() {
|
|||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
if(!res.isAnime) invoke2embed(res.imdbId,res.season,res.episode,callback)
|
||||
},
|
||||
)
|
||||
|
||||
return true
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.hexated
|
||||
|
||||
import com.hexated.SoraExtractor.invoke2embed
|
||||
import com.hexated.SoraExtractor.invokeAnimes
|
||||
import com.hexated.SoraExtractor.invokeAsk4Movies
|
||||
import com.hexated.SoraExtractor.invokeDbgo
|
||||
|
@ -355,7 +356,15 @@ class SoraStreamLite : SoraStream() {
|
|||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
if(!res.isAnime) invoke2embed(
|
||||
res.imdbId,
|
||||
res.season,
|
||||
res.episode,
|
||||
callback
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
return true
|
||||
|
|
Loading…
Reference in a new issue