forked from recloudstream/cloudstream
allanime fixes
This commit is contained in:
parent
6a4bcceb44
commit
11e10a9bd8
8 changed files with 96 additions and 54 deletions
|
@ -430,6 +430,7 @@ interface SearchResponse {
|
||||||
enum class ActorRole {
|
enum class ActorRole {
|
||||||
Main,
|
Main,
|
||||||
Supporting,
|
Supporting,
|
||||||
|
Background,
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Actor(
|
data class Actor(
|
||||||
|
@ -509,15 +510,21 @@ interface LoadResponse {
|
||||||
var actors: List<ActorData>?
|
var actors: List<ActorData>?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun LoadResponse.setActorNames(actors: List<String>?) {
|
@JvmName("addActorNames")
|
||||||
|
fun LoadResponse.addActors(actors: List<String>?) {
|
||||||
this.actors = actors?.map { ActorData(Actor(it)) }
|
this.actors = actors?.map { ActorData(Actor(it)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun LoadResponse.setActors(actors: List<Pair<Actor, String?>>?) {
|
@JvmName("addActors")
|
||||||
println("ACTORS: ${actors?.size}")
|
fun LoadResponse.addActors(actors: List<Pair<Actor, String?>>?) {
|
||||||
this.actors = actors?.map { (actor, role) -> ActorData(actor, roleString = role) }
|
this.actors = actors?.map { (actor, role) -> ActorData(actor, roleString = role) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmName("addActorsRole")
|
||||||
|
fun LoadResponse.addActors(actors: List<Pair<Actor, ActorRole?>>?) {
|
||||||
|
this.actors = actors?.map { (actor, role) -> ActorData(actor, role = role) }
|
||||||
|
}
|
||||||
|
|
||||||
fun LoadResponse.setDuration(input: String?) {
|
fun LoadResponse.setDuration(input: String?) {
|
||||||
val cleanInput = input?.trim()?.replace(" ","") ?: return
|
val cleanInput = input?.trim()?.replace(" ","") ?: return
|
||||||
Regex("([0-9]*)h.*?([0-9]*)m").find(cleanInput)?.groupValues?.let { values ->
|
Regex("([0-9]*)h.*?([0-9]*)m").find(cleanInput)?.groupValues?.let { values ->
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.animeproviders
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
|
||||||
|
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
@ -163,12 +165,34 @@ class AllAnimeProvider : MainAPI() {
|
||||||
}) else null)
|
}) else null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val characters = soup.select("div.character > div.card-character-box")?.mapNotNull {
|
||||||
|
val img = it?.selectFirst("img")?.attr("src") ?: return@mapNotNull null
|
||||||
|
val name = it.selectFirst("div > a")?.ownText() ?: return@mapNotNull null
|
||||||
|
val role = when (it.selectFirst("div > .text-secondary")?.text()?.trim()) {
|
||||||
|
"Main" -> ActorRole.Main
|
||||||
|
"Supporting" -> ActorRole.Supporting
|
||||||
|
"Background" -> ActorRole.Background
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
Pair(Actor(name, img), role)
|
||||||
|
}
|
||||||
|
|
||||||
|
val recommendations = soup.select("#suggesction > div > div.p > .swipercard")?.mapNotNull {
|
||||||
|
val recTitle = it?.selectFirst(".showname > a") ?: return@mapNotNull null
|
||||||
|
val recName = recTitle.text() ?: return@mapNotNull null
|
||||||
|
val href = fixUrlNull(recTitle.attr("href")) ?: return@mapNotNull null
|
||||||
|
val img = it.selectFirst(".image > img").attr("src") ?: return@mapNotNull null
|
||||||
|
AnimeSearchResponse(recName, href, this.name, TvType.Anime, img)
|
||||||
|
}
|
||||||
|
|
||||||
return newAnimeLoadResponse(title, url, TvType.Anime) {
|
return newAnimeLoadResponse(title, url, TvType.Anime) {
|
||||||
posterUrl = poster
|
posterUrl = poster
|
||||||
year = showData.airedStart?.year
|
year = showData.airedStart?.year
|
||||||
|
|
||||||
addEpisodes(DubStatus.Subbed, episodes.first)
|
addEpisodes(DubStatus.Subbed, episodes.first)
|
||||||
addEpisodes(DubStatus.Dubbed, episodes.second)
|
addEpisodes(DubStatus.Dubbed, episodes.second)
|
||||||
|
addActors(characters)
|
||||||
|
this.recommendations = recommendations
|
||||||
|
|
||||||
showStatus = getStatus(showData.status.toString())
|
showStatus = getStatus(showData.status.toString())
|
||||||
|
|
||||||
|
@ -259,58 +283,60 @@ class AllAnimeProvider : MainAPI() {
|
||||||
val sources = Regex("""sourceUrl[:=]"(.+?)"""").findAll(html).toList()
|
val sources = Regex("""sourceUrl[:=]"(.+?)"""").findAll(html).toList()
|
||||||
.map { URLDecoder.decode(it.destructured.component1().sanitize(), "UTF-8") }
|
.map { URLDecoder.decode(it.destructured.component1().sanitize(), "UTF-8") }
|
||||||
sources.apmap {
|
sources.apmap {
|
||||||
var link = it
|
safeApiCall {
|
||||||
if (URI(link).isAbsolute || link.startsWith("//")) {
|
var link = it.replace(" ", "%20")
|
||||||
if (link.startsWith("//")) link = "https:$it"
|
if (URI(link).isAbsolute || link.startsWith("//")) {
|
||||||
|
if (link.startsWith("//")) link = "https:$it"
|
||||||
|
|
||||||
if (Regex("""streaming\.php\?""").matches(link)) {
|
if (Regex("""streaming\.php\?""").matches(link)) {
|
||||||
// for now ignore
|
// for now ignore
|
||||||
} else if (!embedIsBlacklisted(link)) {
|
} else if (!embedIsBlacklisted(link)) {
|
||||||
if (URI(link).path.contains(".m3u")) {
|
if (URI(link).path.contains(".m3u")) {
|
||||||
getM3u8Qualities(link, data, URI(link).host).forEach(callback)
|
getM3u8Qualities(link, data, URI(link).host).forEach(callback)
|
||||||
} else {
|
|
||||||
callback(
|
|
||||||
ExtractorLink(
|
|
||||||
"AllAnime - " + URI(link).host,
|
|
||||||
"",
|
|
||||||
link,
|
|
||||||
data,
|
|
||||||
getQualityFromName("1080"),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
link = apiEndPoint + URI(link).path + ".json?" + URI(link).query
|
|
||||||
val response = app.get(link)
|
|
||||||
|
|
||||||
if (response.code < 400) {
|
|
||||||
val links = mapper.readValue<AllAnimeVideoApiResponse>(response.text).links
|
|
||||||
links.forEach { server ->
|
|
||||||
if (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),
|
|
||||||
server.resolutionStr
|
|
||||||
).forEach(callback)
|
|
||||||
} else {
|
} else {
|
||||||
callback(
|
callback(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
"AllAnime - " + URI(server.link).host,
|
"AllAnime - " + URI(link).host,
|
||||||
server.resolutionStr,
|
"",
|
||||||
server.link,
|
link,
|
||||||
"$apiEndPoint/player?uri=" + (if (URI(server.link).host.isNotEmpty()) server.link else apiEndPoint + URI(
|
data,
|
||||||
server.link
|
|
||||||
).path),
|
|
||||||
getQualityFromName("1080"),
|
getQualityFromName("1080"),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
link = apiEndPoint + URI(link).path + ".json?" + URI(link).query
|
||||||
|
val response = app.get(link)
|
||||||
|
|
||||||
|
if (response.code < 400) {
|
||||||
|
val links = mapper.readValue<AllAnimeVideoApiResponse>(response.text).links
|
||||||
|
links.forEach { server ->
|
||||||
|
if (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),
|
||||||
|
server.resolutionStr
|
||||||
|
).forEach(callback)
|
||||||
|
} else {
|
||||||
|
callback(
|
||||||
|
ExtractorLink(
|
||||||
|
"AllAnime - " + URI(server.link).host,
|
||||||
|
server.resolutionStr,
|
||||||
|
server.link,
|
||||||
|
"$apiEndPoint/player?uri=" + (if (URI(server.link).host.isNotEmpty()) server.link else apiEndPoint + URI(
|
||||||
|
server.link
|
||||||
|
).path),
|
||||||
|
getQualityFromName("1080"),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.lagradost.cloudstream3.metaproviders
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.LoadResponse.Companion.setActors
|
import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||||
import com.uwetrottmann.tmdb2.Tmdb
|
import com.uwetrottmann.tmdb2.Tmdb
|
||||||
import com.uwetrottmann.tmdb2.entities.*
|
import com.uwetrottmann.tmdb2.entities.*
|
||||||
|
@ -142,7 +142,7 @@ open class TmdbProvider : MainAPI() {
|
||||||
|
|
||||||
recommendations = (this@toLoadResponse.recommendations
|
recommendations = (this@toLoadResponse.recommendations
|
||||||
?: this@toLoadResponse.similar)?.results?.map { it.toSearchResponse() }
|
?: this@toLoadResponse.similar)?.results?.map { it.toSearchResponse() }
|
||||||
setActors(credits?.cast?.toList().toActors())
|
addActors(credits?.cast?.toList().toActors())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ open class TmdbProvider : MainAPI() {
|
||||||
|
|
||||||
recommendations = (this@toLoadResponse.recommendations
|
recommendations = (this@toLoadResponse.recommendations
|
||||||
?: this@toLoadResponse.similar)?.results?.map { it.toSearchResponse() }
|
?: this@toLoadResponse.similar)?.results?.map { it.toSearchResponse() }
|
||||||
setActors(credits?.cast?.toList().toActors())
|
addActors(credits?.cast?.toList().toActors())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ open class TmdbProvider : MainAPI() {
|
||||||
|
|
||||||
if (response.actors.isNullOrEmpty())
|
if (response.actors.isNullOrEmpty())
|
||||||
tmdb.tvService().credits(id, "en-US").awaitResponse().body()?.let {
|
tmdb.tvService().credits(id, "en-US").awaitResponse().body()?.let {
|
||||||
response.setActors(it.cast?.toActors())
|
response.addActors(it.cast?.toActors())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ open class TmdbProvider : MainAPI() {
|
||||||
|
|
||||||
if (response.actors.isNullOrEmpty())
|
if (response.actors.isNullOrEmpty())
|
||||||
tmdb.moviesService().credits(id).awaitResponse().body()?.let {
|
tmdb.moviesService().credits(id).awaitResponse().body()?.let {
|
||||||
response.setActors(it.cast?.toActors())
|
response.addActors(it.cast?.toActors())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response
|
response
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.LoadResponse.Companion.setActorNames
|
import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
|
||||||
import com.lagradost.cloudstream3.LoadResponse.Companion.setDuration
|
import com.lagradost.cloudstream3.LoadResponse.Companion.setDuration
|
||||||
import com.lagradost.cloudstream3.network.WebViewResolver
|
import com.lagradost.cloudstream3.network.WebViewResolver
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
|
@ -182,7 +182,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() {
|
||||||
this.posterUrl = posterUrl
|
this.posterUrl = posterUrl
|
||||||
this.plot = plot
|
this.plot = plot
|
||||||
setDuration(duration)
|
setDuration(duration)
|
||||||
setActorNames(cast)
|
addActors(cast)
|
||||||
this.tags = tags
|
this.tags = tags
|
||||||
this.recommendations = recommendations
|
this.recommendations = recommendations
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() {
|
||||||
this.year = year
|
this.year = year
|
||||||
this.plot = plot
|
this.plot = plot
|
||||||
setDuration(duration)
|
setDuration(duration)
|
||||||
setActorNames(cast)
|
addActors(cast)
|
||||||
this.tags = tags
|
this.tags = tags
|
||||||
this.recommendations = recommendations
|
this.recommendations = recommendations
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,7 @@ abstract class AbstractPlayerFragment(
|
||||||
val msg = exception.message ?: ""
|
val msg = exception.message ?: ""
|
||||||
val errorName = exception.errorCodeName
|
val errorName = exception.errorCodeName
|
||||||
when (val code = exception.errorCode) {
|
when (val code = exception.errorCode) {
|
||||||
PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND, PlaybackException.ERROR_CODE_IO_NO_PERMISSION, PlaybackException.ERROR_CODE_IO_UNSPECIFIED -> {
|
PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND, PlaybackException.ERROR_CODE_PARSING_CONTAINER_UNSUPPORTED, PlaybackException.ERROR_CODE_IO_NO_PERMISSION, PlaybackException.ERROR_CODE_IO_UNSPECIFIED -> {
|
||||||
showToast(
|
showToast(
|
||||||
activity,
|
activity,
|
||||||
"${ctx.getString(R.string.source_error)}\n$errorName ($code)\n$msg",
|
"${ctx.getString(R.string.source_error)}\n$errorName ($code)\n$msg",
|
||||||
|
|
|
@ -71,6 +71,9 @@ class ActorAdaptor(
|
||||||
ActorRole.Supporting -> {
|
ActorRole.Supporting -> {
|
||||||
R.string.actor_supporting
|
R.string.actor_supporting
|
||||||
}
|
}
|
||||||
|
ActorRole.Background -> {
|
||||||
|
R.string.actor_background
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)?.let { text ->
|
)?.let { text ->
|
||||||
actorExtra.isVisible = true
|
actorExtra.isVisible = true
|
||||||
|
|
|
@ -1080,11 +1080,13 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
|
||||||
DataStoreHelper.getLastWatched(currentId)?.let { resume ->
|
DataStoreHelper.getLastWatched(currentId)?.let { resume ->
|
||||||
if (currentIsMovie == false && episodeList.size >= 3) {
|
if (currentIsMovie == false && episodeList.size >= 3) {
|
||||||
isSeriesVisible = true
|
isSeriesVisible = true
|
||||||
|
|
||||||
result_resume_series_button?.setOnClickListener {
|
result_resume_series_button?.setOnClickListener {
|
||||||
episodeList.firstOrNull { it.id == resume.episodeId }?.let {
|
episodeList.firstOrNull { it.id == resume.episodeId }?.let {
|
||||||
handleAction(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, it))
|
handleAction(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result_resume_series_title?.text =
|
result_resume_series_title?.text =
|
||||||
if (resume.season == null)
|
if (resume.season == null)
|
||||||
"${getString(R.string.episode)} ${resume.episode}"
|
"${getString(R.string.episode)} ${resume.episode}"
|
||||||
|
@ -1098,6 +1100,8 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
|
||||||
}
|
}
|
||||||
result_resume_series_progress_text?.text =
|
result_resume_series_progress_text?.text =
|
||||||
getString(R.string.resume_time_left).format((viewPos.duration - viewPos.position) / (60_000))
|
getString(R.string.resume_time_left).format((viewPos.duration - viewPos.position) / (60_000))
|
||||||
|
} ?: run {
|
||||||
|
isSeriesVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,5 +387,7 @@
|
||||||
<string name="downloaded_file">Downloaded file</string>
|
<string name="downloaded_file">Downloaded file</string>
|
||||||
<string name="actor_main">Main</string>
|
<string name="actor_main">Main</string>
|
||||||
<string name="actor_supporting">Supporting</string>
|
<string name="actor_supporting">Supporting</string>
|
||||||
|
<string name="actor_background">Background</string>
|
||||||
|
|
||||||
<string name="home_source">Source</string>
|
<string name="home_source">Source</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue