fix(fr/franime): Fix video extraction (#1964)
This commit is contained in:
@ -1,12 +1,14 @@
|
|||||||
apply plugin: 'com.android.application'
|
plugins {
|
||||||
apply plugin: 'kotlin-android'
|
alias(libs.plugins.android.application)
|
||||||
apply plugin: 'kotlinx-serialization'
|
alias(libs.plugins.kotlin.android)
|
||||||
|
alias(libs.plugins.kotlin.serialization)
|
||||||
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
extName = 'FrAnime'
|
extName = 'FrAnime'
|
||||||
pkgNameSuffix = 'fr.franime'
|
pkgNameSuffix = 'fr.franime'
|
||||||
extClass = '.FrAnime'
|
extClass = '.FrAnime'
|
||||||
extVersionCode = 3
|
extVersionCode = 4
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
containsNsfw = true
|
containsNsfw = true
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package eu.kanade.tachiyomi.animeextension.fr.franime
|
package eu.kanade.tachiyomi.animeextension.fr.franime
|
||||||
|
|
||||||
import android.net.UrlQuerySanitizer
|
|
||||||
import eu.kanade.tachiyomi.animeextension.fr.franime.dto.Anime
|
import eu.kanade.tachiyomi.animeextension.fr.franime.dto.Anime
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||||
@ -14,15 +13,13 @@ import eu.kanade.tachiyomi.lib.sibnetextractor.SibnetExtractor
|
|||||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.net.URI
|
|
||||||
import kotlin.io.path.Path
|
|
||||||
import kotlin.io.path.name
|
|
||||||
|
|
||||||
class FrAnime : AnimeHttpSource() {
|
class FrAnime : AnimeHttpSource() {
|
||||||
|
|
||||||
@ -41,6 +38,8 @@ class FrAnime : AnimeHttpSource() {
|
|||||||
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient
|
override val client: OkHttpClient = network.cloudflareClient
|
||||||
|
|
||||||
|
override fun headersBuilder() = super.headersBuilder().add("Referer", "$baseUrl/")
|
||||||
|
|
||||||
private val json: Json by injectLazy()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
private val database by lazy {
|
private val database by lazy {
|
||||||
@ -58,9 +57,10 @@ class FrAnime : AnimeHttpSource() {
|
|||||||
// === Episodes
|
// === Episodes
|
||||||
|
|
||||||
override fun fetchEpisodeList(anime: SAnime): Observable<List<SEpisode>> {
|
override fun fetchEpisodeList(anime: SAnime): Observable<List<SEpisode>> {
|
||||||
val stem = Path(URI(anime.url).path).name // WILL break on API update ! name becomes fileName in new versions !
|
val url = (baseUrl + anime.url).toHttpUrl()
|
||||||
val language = UrlQuerySanitizer(anime.url).getValue("lang")
|
val stem = url.encodedPathSegments.last()
|
||||||
val season = UrlQuerySanitizer(anime.url).getValue("s").toInt()
|
val language = url.queryParameter("lang") ?: "vo"
|
||||||
|
val season = url.queryParameter("s")?.toIntOrNull() ?: 1
|
||||||
val animeData = database.first { titleToUrl(it.originalTitle) == stem }
|
val animeData = database.first { titleToUrl(it.originalTitle) == stem }
|
||||||
val episodes = mutableListOf<SEpisode>()
|
val episodes = mutableListOf<SEpisode>()
|
||||||
animeData.seasons[season - 1].episodes.forEachIndexed { index, episode ->
|
animeData.seasons[season - 1].episodes.forEachIndexed { index, episode ->
|
||||||
@ -81,30 +81,30 @@ class FrAnime : AnimeHttpSource() {
|
|||||||
// === Players
|
// === Players
|
||||||
|
|
||||||
override fun fetchVideoList(episode: SEpisode): Observable<List<Video>> {
|
override fun fetchVideoList(episode: SEpisode): Observable<List<Video>> {
|
||||||
val seasonNumber = UrlQuerySanitizer(episode.url).getValue("s").toInt()
|
val url = (baseUrl + episode.url).toHttpUrl()
|
||||||
val episodeNumber = UrlQuerySanitizer(episode.url).getValue("ep").toInt()
|
val seasonNumber = url.queryParameter("s")?.toIntOrNull() ?: 1
|
||||||
val episodeLang = UrlQuerySanitizer(episode.url).getValue("lang")
|
val episodeNumber = url.queryParameter("ep")?.toIntOrNull() ?: 1
|
||||||
val stem = Path(URI(episode.url).path).name
|
val episodeLang = url.queryParameter("lang") ?: "vo"
|
||||||
|
val stem = url.encodedPathSegments.last()
|
||||||
val animeData = database.first { titleToUrl(it.originalTitle) == stem }
|
val animeData = database.first { titleToUrl(it.originalTitle) == stem }
|
||||||
val episodeData = animeData.seasons[seasonNumber - 1].episodes[episodeNumber - 1]
|
val episodeData = animeData.seasons[seasonNumber - 1].episodes[episodeNumber - 1]
|
||||||
val videoBaseUrl = "$baseApiAnimeUrl/${animeData.id}/${seasonNumber - 1}/${episodeNumber - 1}"
|
val videoBaseUrl = "$baseApiAnimeUrl/${animeData.id}/${seasonNumber - 1}/${episodeNumber - 1}"
|
||||||
|
|
||||||
val videos = mutableListOf<Video>()
|
|
||||||
val players = if (episodeLang == "vo") episodeData.languages.vo.players else episodeData.languages.vf.players
|
val players = if (episodeLang == "vo") episodeData.languages.vo.players else episodeData.languages.vf.players
|
||||||
|
|
||||||
players.forEachIndexed { index, playerName ->
|
val videos = players.flatMapIndexed { index, playerName ->
|
||||||
val apiUrl = "$videoBaseUrl/$episodeLang/$index"
|
val apiUrl = "$videoBaseUrl/$episodeLang/$index"
|
||||||
val playerUrl = client.newCall(GET(apiUrl)).execute().body.string()
|
val playerUrl = client.newCall(GET(apiUrl, headers)).execute().body.string()
|
||||||
val playerVideos = when (playerName) {
|
when (playerName) {
|
||||||
"franime_myvi" -> listOf(Video(playerUrl, "FRAnime", playerUrl))
|
"franime_myvi" -> listOf(Video(playerUrl, "FRAnime", playerUrl))
|
||||||
"myvi" -> MytvExtractor(client).videosFromUrl(playerUrl)
|
"myvi" -> MytvExtractor(client).videosFromUrl(playerUrl)
|
||||||
"sendvid" -> SendvidExtractor(client, headers).videosFromUrl(playerUrl)
|
"sendvid" -> SendvidExtractor(client, headers).videosFromUrl(playerUrl)
|
||||||
"sibnet" -> SibnetExtractor(client).videosFromUrl(playerUrl)
|
"sibnet" -> SibnetExtractor(client).videosFromUrl(playerUrl)
|
||||||
"sbfull" -> StreamSBExtractor(client).videosFromUrl(playerUrl, headers)
|
"sbfull" -> StreamSBExtractor(client).videosFromUrl(playerUrl, headers)
|
||||||
else -> null
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
if (playerVideos != null) videos.addAll(playerVideos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Observable.just(videos)
|
return Observable.just(videos)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,26 +165,21 @@ class FrAnime : AnimeHttpSource() {
|
|||||||
val seasonTitle = it.title + if (it.seasons.size > 1) " S${index + 1}" else ""
|
val seasonTitle = it.title + if (it.seasons.size > 1) " S${index + 1}" else ""
|
||||||
val hasVostfr = season.episodes.fold(false) { v, e -> v or e.languages.vo.players.isNotEmpty() }
|
val hasVostfr = season.episodes.fold(false) { v, e -> v or e.languages.vo.players.isNotEmpty() }
|
||||||
val hasVf = season.episodes.fold(false) { v, e -> v or e.languages.vf.players.isNotEmpty() }
|
val hasVf = season.episodes.fold(false) { v, e -> v or e.languages.vf.players.isNotEmpty() }
|
||||||
|
|
||||||
// I want to die for writing this
|
// I want to die for writing this
|
||||||
if (hasVostfr) {
|
val languages = listOfNotNull(
|
||||||
|
if (hasVostfr) Triple("VOSTFR", "vo", hasVf) else null,
|
||||||
|
if (hasVf) Triple("VF", "vf", hasVostfr) else null,
|
||||||
|
)
|
||||||
|
|
||||||
|
languages.forEach { lang ->
|
||||||
entries += SAnime.create().apply {
|
entries += SAnime.create().apply {
|
||||||
title = seasonTitle + if (hasVf) " (VOSTFR)" else ""
|
title = seasonTitle + if (lang.third) " (${lang.first})" else ""
|
||||||
thumbnail_url = it.poster
|
thumbnail_url = it.poster
|
||||||
genre = it.genres.joinToString()
|
genre = it.genres.joinToString()
|
||||||
status = parseStatus(it.status, it.seasons.size, index + 1)
|
status = parseStatus(it.status, it.seasons.size, index + 1)
|
||||||
description = it.description
|
description = it.description
|
||||||
setUrlWithoutDomain("/anime/${titleToUrl(it.originalTitle)}?lang=vo&s=${index + 1}")
|
setUrlWithoutDomain("/anime/${titleToUrl(it.originalTitle)}?lang=${lang.second}&s=${index + 1}")
|
||||||
initialized = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasVf) {
|
|
||||||
entries += SAnime.create().apply {
|
|
||||||
title = seasonTitle + if (hasVostfr) " (VF)" else ""
|
|
||||||
thumbnail_url = it.poster
|
|
||||||
genre = it.genres.joinToString()
|
|
||||||
status = parseStatus(it.status, it.seasons.size, index + 1)
|
|
||||||
description = it.description
|
|
||||||
setUrlWithoutDomain("/anime/${titleToUrl(it.originalTitle)}?lang=vf&s=${index + 1}")
|
|
||||||
initialized = true
|
initialized = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user