Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix(Multi): Fixed Multi source #149

Merged
merged 2 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/all/torrentio/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'Torrentio (Torrent / Debrid)'
extClass = '.Torrentio'
extVersionCode = 1
extVersionCode = 2
containsNsfw = false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
"AllDebrid",
"DebridLink",
"Offcloud",
"TorBox",
)
private val PREF_DEBRID_VALUES = arrayOf(
"none",
Expand All @@ -610,6 +611,7 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
"alldebrid",
"debridlink",
"offcloud",
"torbox",
)

// Sort
Expand Down
2 changes: 1 addition & 1 deletion src/all/torrentioanime/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'Torrentio Anime (Torrent / Debrid)'
extClass = '.Torrentio'
extVersionCode = 9
extVersionCode = 11
containsNsfw = false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
?.let { videos ->
if (preferences.getBoolean(UPCOMING_EP_KEY, UPCOMING_EP_DEFAULT)) { videos } else { videos.filter { video -> (video.released?.let { parseDate(it) } ?: 0L) <= System.currentTimeMillis() } }
}
?.filter { it.thumbnail != null }
?.map { video ->
SEpisode.create().apply {
episode_number = video.episode?.toFloat() ?: 0.0F
Expand Down Expand Up @@ -603,6 +604,7 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
"AllDebrid",
"DebridLink",
"Offcloud",
"TorBox",
)
private val PREF_DEBRID_VALUES = arrayOf(
"none",
Expand All @@ -611,6 +613,7 @@ class Torrentio : ConfigurableAnimeSource, AnimeHttpSource() {
"alldebrid",
"debridlink",
"offcloud",
"torbox",
)

// Sort
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,5 @@ data class EpisodeVideo(
val episode: Int? = null,
val released: String? = null,
val title: String? = null,
val thumbnail: String? = null,
)
2 changes: 1 addition & 1 deletion src/en/aniplay/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ext {
extName = 'AniPlay'
extClass = '.AniPlay'
themePkg = 'anilist'
overrideVersionCode = 6
overrideVersionCode = 8
}

apply from: "$rootDir/common.gradle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import eu.kanade.tachiyomi.animesource.model.Track
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
import eu.kanade.tachiyomi.multisrc.anilist.AniListAnimeHttpSource
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.parallelFlatMapBlocking
import eu.kanade.tachiyomi.util.parallelFlatMap
import eu.kanade.tachiyomi.util.parallelMap
import eu.kanade.tachiyomi.util.parseAs
import kotlinx.serialization.SerializationException
import kotlinx.serialization.encodeToString
Expand All @@ -32,6 +32,7 @@ import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Locale

@Suppress("unused")
class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
override val name = "AniPlay"
override val lang = "en"
Expand Down Expand Up @@ -68,7 +69,7 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
}
}

val baseHost: String get() = "${preferences.getString(PREF_DOMAIN_KEY, PREF_DOMAIN_DEFAULT)}"
private val baseHost: String get() = "${preferences.getString(PREF_DOMAIN_KEY, PREF_DOMAIN_DEFAULT)}"

/* ====================================== Episode List ====================================== */

Expand All @@ -93,22 +94,6 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
val episodeListUrl = response.request.url
val animeId = episodeListUrl.pathSegments[2]

val responsePage = client.newCall(GET("$baseUrl/anime/watch/$animeId")).execute()
val responsePageString = responsePage.body.string()
var idMal: Number? = null
val idMalIndex = responsePageString.indexOf("\\\"idMal\\\":")
if (idMalIndex != -1) {
val startIndex = idMalIndex + "\\\"idMal\\\":".length
val endIndex = responsePageString.indexOf(',', startIndex)
if (endIndex != -1) {
idMal = responsePageString.substring(startIndex, endIndex).toIntOrNull()
}
}
if (idMal == null) {
Log.e("AniPlay", "idMal not found - responsePageString: $responsePageString")
throw Exception("idMal not found")
}

val responseString = response.body.string()
val episodesArrayString = extractEpisodeList(responseString)
if (episodesArrayString == null) {
Expand All @@ -131,7 +116,7 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
source = provider.providerId,
episodeId = episode.id,
episodeNum = episode.number,
hasDub = episode.hasDub,
hasDub = episode.hasDub ?: false,
)
episodeExtras[episodeNumber] = existingEpisodeExtras + listOf(episodeExtra)
}
Expand All @@ -150,7 +135,6 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
.addQueryParameter("id", animeId)
.addQueryParameter("ep", episodeNumber.toString())
.addQueryParameter("extras", episodeExtraString)
.addQueryParameter("idMal", idMal.toString())
.build()

val name = parseEpisodeName(episodeNumber.toString(), episode.title)
Expand All @@ -160,7 +144,7 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
else -> ""
}
val filler = when {
episode.isFiller && isMarkFiller -> " • Filler Episode"
episode.isFiller == true && isMarkFiller -> " • Filler Episode"
else -> ""
}
val scanlator = "Sub$dub$filler"
Expand All @@ -180,7 +164,6 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
override suspend fun getVideoList(episode: SEpisode): List<Video> {
val episodeUrl = episode.url.toHttpUrl()
val animeId = episodeUrl.queryParameter("id") ?: return emptyList()
val idMal = episodeUrl.queryParameter("idMal") ?: return emptyList()
val extras = episodeUrl.queryParameter("extras")
?.let {
try {
Expand All @@ -206,53 +189,63 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
.add("Next-Action", getHeaderValue(baseHost, NEXT_ACTION_SOURCES_LIST))
.build()

val episodeDataList = extras.parallelFlatMapBlocking { extra ->
var timeouts = 0
var maxTimeout = 0
val episodeDataList = extras.parallelFlatMap { extra ->
val languages = mutableListOf("sub").apply {
if (extra.hasDub) add("dub")
}
languages.map { language ->
languages.parallelMap { language ->
maxTimeout += 1
val epNum = if (extra.episodeNum == extra.episodeNum.toInt().toFloat()) {
extra.episodeNum.toInt().toString() // If it has no fractional part, convert it to an integer
} else {
extra.episodeNum.toString() // If it has a fractional part, leave it as a float
}

val requestBody = "[\"$animeId\",$idMal,\"${extra.source}\",\"${extra.episodeId}\",\"$epNum\",\"$language\"]"
val requestBody = "[\"$animeId\",\"${extra.source}\",\"${extra.episodeId}\",\"$epNum\",\"$language\"]"
.toRequestBody("application/json".toMediaType())

val params = mapOf(
"id" to animeId,
"host" to extra.source,
"ep" to epNum,
"type" to language,
)
val builder = Uri.parse("$baseUrl/anime/watch").buildUpon()
val builder = Uri.parse("$baseUrl/anime/watch/$animeId").buildUpon()
params.map { (k, v) -> builder.appendQueryParameter(k, v); }
val url = builder.build().toString()
try {
val request = POST(url, headersWithAction, requestBody)
val response = client.newCall(request).execute()

val responseString = response.body.string()
val sourcesString = responseString.split("1:").last()
if (sourcesString.startsWith("null")) return@map null
val sourcesString = extractSourcesList(responseString) ?: return@parallelMap null
val data = sourcesString.parseAs<VideoSourceResponse>()

EpisodeData(
source = extra.source,
language = language,
response = data,
)
} catch (e: java.net.SocketTimeoutException) {
timeouts += 1
null
} catch (e: IOException) {
Log.w("AniPlay", "VideoList $url IOException", e)
timeouts = -999
null // Return null to be filtered out
} catch (e: Exception) {
Log.w("AniPlay", "VideoList $url Exception", e)
timeouts = -999
null // Return null to be filtered out
}
}.filterNotNull() // Filter out null values due to errors
}

if (maxTimeout == timeouts && timeouts != 0) {
throw Exception("Timed out")
}

val videos = episodeDataList.flatMap { episodeData ->
val defaultSource = episodeData.response.sources?.firstOrNull {
it.quality in listOf("default", "auto")
Expand All @@ -263,19 +256,23 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
?.map { Track(it.url, it.lang) }
?: emptyList()

playlistUtils.extractFromHls(
playlistUrl = defaultSource.url,
videoNameGen = { quality ->
val serverName = getServerName(episodeData.source)
val typeName = when {
subtitles.isNotEmpty() -> "SoftSub"
else -> getTypeName(episodeData.language)
}

"$serverName - $quality - $typeName"
},
subtitleList = subtitles,
)
try {
playlistUtils.extractFromHls(
playlistUrl = defaultSource.url,
videoNameGen = { quality ->
val serverName = getServerName(episodeData.source)
val typeName = when {
subtitles.isNotEmpty() -> "SoftSub"
else -> getTypeName(episodeData.language)
}
"$serverName - $quality - $typeName"
},
subtitleList = subtitles,
)
} catch (e: Exception) {
Log.e("AniPlay", "extractFromHls Error: $e")
emptyList()
}
}

return videos.sort()
Expand All @@ -294,7 +291,15 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
}

private fun extractEpisodeList(input: String): String? {
val startMarker = "1:["
return extractList(input, '[', ']')
}

private fun extractSourcesList(input: String): String? {
return extractList(input, '{', '}')
}

private fun extractList(input: String, bracket1: Char, bracket2: Char): String? {
val startMarker = "1:$bracket1"
val list1Index = input.indexOf(startMarker)
if (list1Index == -1) return null

Expand All @@ -304,8 +309,8 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {

while (endIndex < input.length && bracketCount > 0) {
when (input[endIndex]) {
'[' -> bracketCount++
']' -> bracketCount--
bracket1 -> bracketCount++
bracket2 -> bracketCount--
}
endIndex++
}
Expand Down Expand Up @@ -419,11 +424,17 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
}
private fun getServerName(value: String): String {
val index = PREF_SERVER_ENTRY_VALUES.indexOf(value)
if (index == -1) {
return "Other"
}
return PREF_SERVER_ENTRIES[index]
}

private fun getTypeName(value: String): String {
val index = PREF_TYPE_ENTRY_VALUES.indexOf(value)
if (index == -1) {
return "Other"
}
return PREF_TYPE_ENTRIES[index]
}

Expand All @@ -445,7 +456,7 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource {
private const val PREF_DOMAIN_DEFAULT = "aniplaynow.live"

private const val PREF_SERVER_KEY = "server"
private val PREF_SERVER_ENTRIES = arrayOf("Kuro (Gogoanime)", "Yuki (HiAnime)", "Yuno (Yugenanime)", "Anya (AniMixPlay)")
private val PREF_SERVER_ENTRIES = arrayOf("Kuro", "Yuki", "Yuno", "Anya")
private val PREF_SERVER_ENTRY_VALUES = arrayOf("kuro", "yuki", "yuno", "anya")
private const val PREF_SERVER_DEFAULT = "kuro"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ data class EpisodeListResponse(
data class Episode(
val id: String,
val number: Float,
val title: String,
val hasDub: Boolean,
val isFiller: Boolean,
val title: String?,
val hasDub: Boolean?,
val isFiller: Boolean?,
val img: String?,
val description: String?,
val createdAt: String?,
Expand Down
2 changes: 1 addition & 1 deletion src/en/dramacool/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'DramaCool'
extClass = '.DramaCool'
extVersionCode = 53
extVersionCode = 54
}

apply from: "$rootDir/common.gradle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class DramaCool : ConfigurableAnimeSource, ParsedAnimeHttpSource() {

// TODO: Check frequency of url changes to potentially
// add back overridable baseurl preference
override val baseUrl = "https://asianc.sh/"
override val baseUrl = "https://asianc.co/"

override val lang = "en"

Expand Down
11 changes: 1 addition & 10 deletions src/pt/vizer/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
ext {
extName = 'Vizer.tv'
extClass = '.Vizer'
extVersionCode = 18
extVersionCode = 19
isNsfw = true
}

apply from: "$rootDir/common.gradle"

dependencies {
implementation(project(':lib:fireplayer-extractor'))
implementation(project(':lib:mixdrop-extractor'))
implementation(project(':lib:playlist-utils'))
implementation(project(':lib:streamtape-extractor'))
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
}
Loading
Loading