mirror of
https://github.com/yuzono/anime-extensions.git
synced 2026-06-13 13:39:44 +00:00
AnimeStream (multi-src): Refactor & add extractors (#397)
* Use suspend methods * Use helpers * AnimeIndo: Avoid crash when initializing filter list
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
package eu.kanade.tachiyomi.multisrc.animestream
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
@@ -21,11 +21,12 @@ import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters.SubFilter
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters.TypeFilter
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import keiyoushi.utils.addListPreference
|
||||
import keiyoushi.utils.getPreferencesLazy
|
||||
import keiyoushi.utils.parallelCatchingFlatMapBlocking
|
||||
import keiyoushi.utils.tryParse
|
||||
import keiyoushi.utils.useAsJsoup
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
@@ -58,11 +59,19 @@ abstract class AnimeStream(
|
||||
"pt-BR" -> "Qualidade preferida"
|
||||
else -> "Preferred quality"
|
||||
}
|
||||
protected open val prefQualityValues = arrayOf("1080p", "720p", "480p", "360p")
|
||||
protected open val prefQualityEntries = prefQualityValues
|
||||
protected open val prefQualityValues = listOf("1080p", "720p", "480p", "360p")
|
||||
protected open val prefQualityEntries: List<String>
|
||||
get() = prefQualityValues
|
||||
|
||||
protected open val videoSortPrefKey = prefQualityKey
|
||||
protected open val videoSortPrefDefault = prefQualityDefault
|
||||
protected open val videoSortPrefKey: String
|
||||
get() = prefQualityKey
|
||||
protected open val videoSortPrefDefault: String
|
||||
get() = prefQualityDefault
|
||||
|
||||
protected open val SharedPreferences.qualityPref: String
|
||||
get() = getString(prefQualityKey, prefQualityDefault) ?: prefQualityDefault
|
||||
protected open val SharedPreferences.videoSortPref: String
|
||||
get() = getString(videoSortPrefKey, videoSortPrefDefault) ?: videoSortPrefDefault
|
||||
|
||||
protected open val dateFormatter by lazy {
|
||||
val locale = when (lang) {
|
||||
@@ -125,7 +134,7 @@ abstract class AnimeStream(
|
||||
}
|
||||
|
||||
protected open fun searchAnimeByPathParse(response: Response): AnimesPage {
|
||||
val details = animeDetailsParse(response.asJsoup()).apply {
|
||||
val details = animeDetailsParse(response.useAsJsoup()).apply {
|
||||
setUrlWithoutDomain(response.request.url.toString())
|
||||
initialized = true
|
||||
}
|
||||
@@ -167,13 +176,14 @@ abstract class AnimeStream(
|
||||
|
||||
protected open val filtersSelector = "span.sec1 > div.filter > ul"
|
||||
|
||||
private fun fetchFilterList() {
|
||||
protected open suspend fun fetchFilterList() {
|
||||
if (fetchFilters && !AnimeStreamFilters.filterInitialized()) {
|
||||
AnimeStreamFilters.filterElements = runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
client.newCall(GET(animeListUrl)).execute()
|
||||
.asJsoup()
|
||||
.select(filtersSelector)
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
AnimeStreamFilters.filterElements =
|
||||
client.newCall(GET(animeListUrl)).awaitSuccess()
|
||||
.useAsJsoup()
|
||||
.select(filtersSelector)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,7 +231,7 @@ abstract class AnimeStream(
|
||||
else -> "Order"
|
||||
}
|
||||
|
||||
override fun getFilterList(): AnimeFilterList = if (fetchFilters && AnimeStreamFilters.filterInitialized()) {
|
||||
override fun getFilterList(): AnimeFilterList = if (fetchFilters && AnimeStreamFilters.filterInitialized() && AnimeStreamFilters.filterElements.isNotEmpty()) {
|
||||
AnimeFilterList(
|
||||
GenresFilter(genresFilterText),
|
||||
SeasonFilter(seasonsFilterText),
|
||||
@@ -290,7 +300,7 @@ abstract class AnimeStream(
|
||||
|
||||
// ============================== Episodes ==============================
|
||||
override fun episodeListParse(response: Response): List<SEpisode> {
|
||||
val doc = response.asJsoup()
|
||||
val doc = response.useAsJsoup()
|
||||
return doc.select(episodeListSelector()).map(::episodeFromElement)
|
||||
}
|
||||
|
||||
@@ -311,14 +321,14 @@ abstract class AnimeStream(
|
||||
episode_number = it.substringBefore(" ").toFloatOrNull() ?: 0F
|
||||
}
|
||||
element.selectFirst(".epl-sub")?.text()?.let { scanlator = it }
|
||||
date_upload = element.selectFirst(".epl-date")?.text().toDate()
|
||||
date_upload = element.selectFirst(".epl-date")?.text().let { dateFormatter.tryParse(it) }
|
||||
}
|
||||
|
||||
// ============================ Video Links =============================
|
||||
override fun videoListSelector() = "select.mirror > option[data-index], ul.mirror a[data-em]"
|
||||
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val items = response.asJsoup().select(videoListSelector())
|
||||
val items = response.useAsJsoup().select(videoListSelector())
|
||||
return items.parallelCatchingFlatMapBlocking { element ->
|
||||
val name = element.text()
|
||||
val url = getHosterUrl(element)
|
||||
@@ -326,7 +336,7 @@ abstract class AnimeStream(
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun getHosterUrl(element: Element): String {
|
||||
protected open suspend fun getHosterUrl(element: Element): String {
|
||||
val encodedData = when (element.tagName()) {
|
||||
"option" -> element.attr("value")
|
||||
"a" -> element.attr("data-em")
|
||||
@@ -337,13 +347,13 @@ abstract class AnimeStream(
|
||||
}
|
||||
|
||||
// Taken from LuciferDonghua
|
||||
protected open fun getHosterUrl(encodedData: String): String {
|
||||
protected open suspend fun getHosterUrl(encodedData: String): String {
|
||||
val doc = if (encodedData.toHttpUrlOrNull() == null) {
|
||||
Base64.decode(encodedData, Base64.DEFAULT)
|
||||
.let(::String) // bytearray -> string
|
||||
.let(Jsoup::parse) // string -> document
|
||||
} else {
|
||||
client.newCall(GET(encodedData, headers)).execute().asJsoup()
|
||||
client.newCall(GET(encodedData, headers)).awaitSuccess().useAsJsoup()
|
||||
}
|
||||
|
||||
return doc.selectFirst("iframe[src~=.]")?.safeUrl()
|
||||
@@ -359,7 +369,7 @@ abstract class AnimeStream(
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun getVideoList(url: String, name: String): List<Video> {
|
||||
protected open suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
Log.i(name, "getVideoList -> URL => $url || Name => $name")
|
||||
return emptyList()
|
||||
}
|
||||
@@ -370,27 +380,19 @@ abstract class AnimeStream(
|
||||
|
||||
// ============================== Settings ==============================
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
val videoQualityPref = ListPreference(screen.context).apply {
|
||||
key = prefQualityKey
|
||||
title = prefQualityTitle
|
||||
entries = prefQualityEntries
|
||||
entryValues = prefQualityValues
|
||||
setDefaultValue(prefQualityDefault)
|
||||
summary = "%s"
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val selected = newValue as String
|
||||
val index = findIndexOfValue(selected)
|
||||
val entry = entryValues[index] as String
|
||||
preferences.edit().putString(key, entry).commit()
|
||||
}
|
||||
}
|
||||
|
||||
screen.addPreference(videoQualityPref)
|
||||
screen.addListPreference(
|
||||
key = prefQualityKey,
|
||||
title = prefQualityTitle,
|
||||
entries = prefQualityEntries,
|
||||
entryValues = prefQualityValues,
|
||||
default = prefQualityDefault,
|
||||
summary = "%s",
|
||||
)
|
||||
}
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(videoSortPrefKey, videoSortPrefDefault)!!
|
||||
val quality = preferences.videoSortPref
|
||||
return sortedWith(
|
||||
compareBy { it.quality.contains(quality, true) },
|
||||
).reversed()
|
||||
@@ -407,12 +409,6 @@ abstract class AnimeStream(
|
||||
selectFirst("a")?.text() ?: ownText()
|
||||
}
|
||||
|
||||
protected open fun String?.toDate(): Long = this?.let {
|
||||
runCatching {
|
||||
dateFormatter.parse(trim())?.time
|
||||
}.getOrNull()
|
||||
} ?: 0L
|
||||
|
||||
/**
|
||||
* Tries to get the image url via various possible attributes.
|
||||
* Taken from Tachiyomi's Madara multisrc.
|
||||
|
||||
@@ -15,7 +15,7 @@ object AnimeStreamFilters {
|
||||
fun toQueryPart() = vals[state].second
|
||||
}
|
||||
|
||||
open class CheckBoxFilterList(name: String, val pairs: Array<Pair<String, String>>) : AnimeFilter.Group<AnimeFilter.CheckBox>(name, pairs.map { CheckBoxVal(it.first, false) })
|
||||
open class CheckBoxFilterList(name: String, pairs: Array<Pair<String, String>>) : AnimeFilter.Group<AnimeFilter.CheckBox>(name, pairs.map { CheckBoxVal(it.first, false) })
|
||||
|
||||
private class CheckBoxVal(name: String, state: Boolean = false) : AnimeFilter.CheckBox(name, state)
|
||||
|
||||
@@ -69,13 +69,14 @@ object AnimeStreamFilters {
|
||||
|
||||
fun filterInitialized() = ::filterElements.isInitialized
|
||||
|
||||
fun getPairListByIndex(index: Int) = filterElements.get(index)
|
||||
.select("li")
|
||||
.map { element ->
|
||||
val key = element.selectFirst("label")!!.text()
|
||||
val value = element.selectFirst("input")!!.attr("value")
|
||||
fun getPairListByIndex(index: Int) = filterElements.getOrNull(index)
|
||||
?.select("li")
|
||||
?.mapNotNull { element ->
|
||||
val key = element.selectFirst("label")?.text() ?: return@mapNotNull null
|
||||
val value = element.selectFirst("input")?.attr("value") ?: return@mapNotNull null
|
||||
Pair(key, value)
|
||||
}.toTypedArray()
|
||||
}?.toTypedArray()
|
||||
?: arrayOf("" to "")
|
||||
|
||||
private val GENRES_LIST by lazy { getPairListByIndex(0) }
|
||||
private val SEASON_LIST by lazy { getPairListByIndex(1) }
|
||||
|
||||
7
lib/rumbleextractor/build.gradle.kts
Normal file
7
lib/rumbleextractor/build.gradle.kts
Normal file
@@ -0,0 +1,7 @@
|
||||
plugins {
|
||||
alias(kei.plugins.library)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":lib:playlistutils"))
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package aniyomi.lib.rumbleextractor
|
||||
|
||||
import aniyomi.lib.playlistutils.PlaylistUtils
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class RumbleExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
|
||||
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||
val id = extractRumbleId(url) ?: return emptyList()
|
||||
val sourceUrl = "https://rumble.com/hls-vod/$id/playlist.m3u8"
|
||||
return playlistUtils.extractFromHls(sourceUrl, referer = url, subtitleList = emptyList(), videoNameGen = { q -> "$prefix $q" })
|
||||
}
|
||||
|
||||
private val regex by lazy { Regex("""rumble\.com/embed/v([a-zA-Z0-9]+)""") }
|
||||
|
||||
private fun extractRumbleId(url: String): String? = regex.find(url)?.groupValues?.get(1)
|
||||
}
|
||||
8
lib/streamplayextractor/build.gradle.kts
Normal file
8
lib/streamplayextractor/build.gradle.kts
Normal file
@@ -0,0 +1,8 @@
|
||||
plugins {
|
||||
alias(kei.plugins.library)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":lib:playlistutils"))
|
||||
implementation(project(":lib:unpacker"))
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package aniyomi.lib.streamplayextractor
|
||||
|
||||
import aniyomi.lib.playlistutils.PlaylistUtils
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import keiyoushi.lib.jsunpacker.JsUnpacker
|
||||
import keiyoushi.utils.UrlUtils
|
||||
import keiyoushi.utils.parallelCatchingFlatMap
|
||||
import keiyoushi.utils.parseAs
|
||||
import keiyoushi.utils.useAsJsoup
|
||||
import kotlinx.serialization.Serializable
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
|
||||
class StreamPlayExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
|
||||
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
|
||||
|
||||
suspend fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||
val document = client.newCall(
|
||||
GET(url, headers),
|
||||
).awaitSuccess().useAsJsoup()
|
||||
|
||||
return document.select("#servers a").parallelCatchingFlatMap { element ->
|
||||
extractAndDecodeFromDocument(element.attr("abs:href"), "$prefix ${element.text()}")
|
||||
}
|
||||
}
|
||||
|
||||
private val kakenRegex by lazy { Regex("window\\.kaken ?= ?\"([^\"]+)\";") }
|
||||
|
||||
/**
|
||||
* Server 3 has issue with playlist compatibility, it only plays the first segment
|
||||
*/
|
||||
private suspend fun extractAndDecodeFromDocument(url: String, prefix: String): List<Video> {
|
||||
val document = client.newCall(
|
||||
GET(url, headers),
|
||||
).awaitSuccess().useAsJsoup()
|
||||
|
||||
// Find script containing the packed code
|
||||
val packedScript = document.selectFirst("script:containsData(function(p,a,c,k,e,d))")
|
||||
|
||||
val kaken = if (packedScript != null) {
|
||||
val scriptContent = packedScript.data()
|
||||
JsUnpacker.unpackAndCombine(scriptContent)?.let {
|
||||
kakenRegex.find(it)?.groupValues?.get(1)
|
||||
}
|
||||
} else {
|
||||
// For mobile UA, it's non-packed
|
||||
document.selectFirst("script:containsData(window.kaken)")
|
||||
?.data()?.let {
|
||||
// Extract kaken
|
||||
kakenRegex.find(it)?.groupValues?.get(1)
|
||||
}
|
||||
} ?: return emptyList()
|
||||
|
||||
val httpUrl = url.toHttpUrlOrNull() ?: return emptyList()
|
||||
|
||||
val apiHeaders = headers.newBuilder().apply {
|
||||
add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||
add("Origin", "${httpUrl.scheme}://${httpUrl.host}")
|
||||
add("Referer", url)
|
||||
add("X-Requested-With", "XMLHttpRequest")
|
||||
}.build()
|
||||
|
||||
val apiResponse = client.newCall(
|
||||
POST(
|
||||
"https://play.streamplay.co.in/api/",
|
||||
headers = apiHeaders,
|
||||
body = kaken.toRequestBody("text/plain".toMediaType()),
|
||||
),
|
||||
).awaitSuccess().parseAs<APIResponse>()
|
||||
|
||||
val subtitleList = apiResponse.tracks?.let { t ->
|
||||
t.map { Track(it.file, it.label) }
|
||||
} ?: emptyList()
|
||||
|
||||
val videos = apiResponse.sources.parallelCatchingFlatMap { source ->
|
||||
val sourceUrl = UrlUtils.fixUrl(source.videoUrl) ?: return@parallelCatchingFlatMap emptyList()
|
||||
if (source.type == "hls" && sourceUrl.endsWith("master.m3u8")) {
|
||||
playlistUtils.extractFromHls(
|
||||
playlistUrl = sourceUrl,
|
||||
referer = url,
|
||||
subtitleList = subtitleList,
|
||||
videoNameGen = { q -> "$prefix $q (StreamPlay)" },
|
||||
)
|
||||
} else {
|
||||
listOf(
|
||||
Video(
|
||||
sourceUrl,
|
||||
"$prefix (StreamPlay) Original",
|
||||
sourceUrl,
|
||||
headers = headers.newBuilder()
|
||||
.set("Referer", url)
|
||||
.build(),
|
||||
subtitleTracks = subtitleList,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
return videos
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class APIResponse(
|
||||
val sources: List<SourceObject>,
|
||||
val tracks: List<TrackObject>? = null,
|
||||
) {
|
||||
@Serializable
|
||||
data class SourceObject(
|
||||
val file: String,
|
||||
val label: String,
|
||||
val type: String,
|
||||
) {
|
||||
val videoUrl: String
|
||||
get() = file.replace("master.txt", "master.m3u8")
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class TrackObject(
|
||||
val file: String,
|
||||
val label: String,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package eu.kanade.tachiyomi.animeextension.all.animexin
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import aniyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import aniyomi.lib.doodextractor.DoodExtractor
|
||||
@@ -10,7 +10,8 @@ import eu.kanade.tachiyomi.animeextension.all.animexin.extractors.VidstreamingEx
|
||||
import eu.kanade.tachiyomi.animeextension.all.animexin.extractors.YouTubeExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import keiyoushi.utils.addListPreference
|
||||
import keiyoushi.utils.delegate
|
||||
|
||||
class AnimeXin :
|
||||
AnimeStream(
|
||||
@@ -28,9 +29,9 @@ class AnimeXin :
|
||||
private val vidstreamingExtractor by lazy { VidstreamingExtractor(client) }
|
||||
private val youTubeExtractor by lazy { YouTubeExtractor(client) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
val prefix = "$name - "
|
||||
when {
|
||||
return when {
|
||||
url.contains("ok.ru") -> okruExtractor.videosFromUrl(url, prefix)
|
||||
|
||||
url.contains("dailymotion") -> dailymotionExtractor.videosFromUrl(url, prefix)
|
||||
@@ -57,27 +58,22 @@ class AnimeXin :
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
super.setupPreferenceScreen(screen) // Quality preferences
|
||||
|
||||
ListPreference(screen.context).apply {
|
||||
key = PREF_LANG_KEY
|
||||
title = PREF_LANG_TITLE
|
||||
entries = PREF_LANG_VALUES
|
||||
entryValues = PREF_LANG_VALUES
|
||||
setDefaultValue(PREF_LANG_DEFAULT)
|
||||
summary = "%s"
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val selected = newValue as String
|
||||
val index = findIndexOfValue(selected)
|
||||
val entry = entryValues[index] as String
|
||||
preferences.edit().putString(key, entry).commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
screen.addListPreference(
|
||||
key = PREF_LANG_KEY,
|
||||
title = PREF_LANG_TITLE,
|
||||
entries = PREF_LANG_VALUES,
|
||||
entryValues = PREF_LANG_VALUES,
|
||||
default = PREF_LANG_DEFAULT,
|
||||
summary = "%s",
|
||||
)
|
||||
}
|
||||
|
||||
private val SharedPreferences.langPref by preferences.delegate(PREF_LANG_KEY, PREF_LANG_DEFAULT)
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(prefQualityKey, prefQualityDefault)!!
|
||||
val language = preferences.getString(PREF_LANG_KEY, PREF_LANG_DEFAULT)!!
|
||||
val quality = preferences.videoSortPref
|
||||
val language = preferences.langPref
|
||||
|
||||
return sortedWith(
|
||||
compareBy(
|
||||
@@ -91,7 +87,7 @@ class AnimeXin :
|
||||
private const val PREF_LANG_KEY = "preferred_language"
|
||||
private const val PREF_LANG_TITLE = "Preferred Video Language"
|
||||
private const val PREF_LANG_DEFAULT = "All Sub"
|
||||
private val PREF_LANG_VALUES = arrayOf(
|
||||
private val PREF_LANG_VALUES = listOf(
|
||||
"All Sub", "Arabic", "English", "German", "Indonesia", "Italian",
|
||||
"Polish", "Portuguese", "Spanish", "Thai", "Turkish",
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package eu.kanade.tachiyomi.animeextension.all.chineseanime
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import aniyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import aniyomi.lib.streamwishextractor.StreamWishExtractor
|
||||
@@ -8,7 +8,8 @@ import aniyomi.lib.vidhideextractor.VidHideExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.all.chineseanime.extractors.VatchusExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import keiyoushi.utils.addListPreference
|
||||
import keiyoushi.utils.delegate
|
||||
|
||||
class ChineseAnime :
|
||||
AnimeStream(
|
||||
@@ -32,13 +33,13 @@ class ChineseAnime :
|
||||
private val vidHideExtractor by lazy { VidHideExtractor(client, headers) }
|
||||
private val vatchusExtractor by lazy { VatchusExtractor(client, headers) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
val prefix = "$name - "
|
||||
return when {
|
||||
url.contains("dailymotion") -> dailymotionExtractor.videosFromUrl(url, prefix)
|
||||
url.contains("embedwish") -> streamwishExtractor.videosFromUrl(url, prefix)
|
||||
url.contains("vatchus") -> vatchusExtractor.videosFromUrl(url, prefix)
|
||||
url.contains("donghua.xyz/v/") -> runBlocking { vidHideExtractor.videosFromUrl(url) { "$prefix $it" } }
|
||||
url.contains("donghua.xyz/v/") -> vidHideExtractor.videosFromUrl(url) { "$prefix $it" }
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
@@ -46,29 +47,23 @@ class ChineseAnime :
|
||||
// ============================== Settings ==============================
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
super.setupPreferenceScreen(screen) // Quality preferences
|
||||
val videoLangPref = ListPreference(screen.context).apply {
|
||||
key = PREF_LANG_KEY
|
||||
title = PREF_LANG_TITLE
|
||||
entries = PREF_LANG_VALUES
|
||||
entryValues = PREF_LANG_VALUES
|
||||
setDefaultValue(PREF_LANG_DEFAULT)
|
||||
summary = "%s"
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val selected = newValue as String
|
||||
val index = findIndexOfValue(selected)
|
||||
val entry = entryValues[index] as String
|
||||
preferences.edit().putString(key, entry).commit()
|
||||
}
|
||||
}
|
||||
|
||||
screen.addPreference(videoLangPref)
|
||||
screen.addListPreference(
|
||||
key = PREF_LANG_KEY,
|
||||
title = PREF_LANG_TITLE,
|
||||
entries = PREF_LANG_VALUES,
|
||||
entryValues = PREF_LANG_VALUES,
|
||||
default = PREF_LANG_DEFAULT,
|
||||
summary = "%s",
|
||||
)
|
||||
}
|
||||
|
||||
private val SharedPreferences.langPref by preferences.delegate(PREF_LANG_KEY, PREF_LANG_DEFAULT)
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(prefQualityKey, prefQualityDefault)!!
|
||||
val language = preferences.getString(PREF_LANG_KEY, PREF_LANG_DEFAULT)!!
|
||||
val quality = preferences.videoSortPref
|
||||
val language = preferences.langPref
|
||||
|
||||
return sortedWith(
|
||||
compareBy(
|
||||
@@ -82,7 +77,7 @@ class ChineseAnime :
|
||||
private const val PREF_LANG_KEY = "preferred_language"
|
||||
private const val PREF_LANG_TITLE = "Preferred Video Language"
|
||||
private const val PREF_LANG_DEFAULT = "All Sub"
|
||||
private val PREF_LANG_VALUES = arrayOf(
|
||||
private val PREF_LANG_VALUES = listOf(
|
||||
"All Sub", "Arabic", "English", "Indonesia", "Persian", "Malay",
|
||||
"Polish", "Portuguese", "Spanish", "Thai", "Vietnamese",
|
||||
)
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package eu.kanade.tachiyomi.animeextension.all.lmanime
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import aniyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import aniyomi.lib.mp4uploadextractor.Mp4uploadExtractor
|
||||
import aniyomi.lib.streamwishextractor.StreamWishExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import keiyoushi.utils.addListPreference
|
||||
import keiyoushi.utils.addSetPreference
|
||||
import keiyoushi.utils.delegate
|
||||
import keiyoushi.utils.parallelCatchingFlatMapBlocking
|
||||
import keiyoushi.utils.useAsJsoup
|
||||
import okhttp3.Response
|
||||
|
||||
class LMAnime :
|
||||
@@ -19,12 +21,11 @@ class LMAnime :
|
||||
"https://lmanime.com",
|
||||
) {
|
||||
// ============================ Video Links =============================
|
||||
override val prefQualityValues = arrayOf("144p", "288p", "480p", "720p", "1080p")
|
||||
override val prefQualityEntries = prefQualityValues
|
||||
override val prefQualityValues = listOf("144p", "288p", "480p", "720p", "1080p")
|
||||
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val items = response.asJsoup().select(videoListSelector())
|
||||
val allowed = preferences.getStringSet(PREF_ALLOWED_LANGS_KEY, PREF_ALLOWED_LANGS_DEFAULT)!!
|
||||
val items = response.useAsJsoup().select(videoListSelector())
|
||||
val allowed = preferences.allowedLangsPref
|
||||
return items
|
||||
.filter { element ->
|
||||
val text = element.text()
|
||||
@@ -40,11 +41,11 @@ class LMAnime :
|
||||
private val dailyExtractor by lazy { DailymotionExtractor(client, headers) }
|
||||
private val mp4uploadExtractor by lazy { Mp4uploadExtractor(client) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
val prefix = "($name) - "
|
||||
return when {
|
||||
"dailymotion" in url -> dailyExtractor.videosFromUrl(url, "Dailymotion ($name)")
|
||||
"mp4upload" in url -> mp4uploadExtractor.videosFromUrl(url, headers, "$prefix")
|
||||
"mp4upload" in url -> mp4uploadExtractor.videosFromUrl(url, headers, prefix)
|
||||
"filelions" in url -> streamwishExtractor.videosFromUrl(url, "StreamWish ($name)")
|
||||
else -> emptyList()
|
||||
}
|
||||
@@ -55,38 +56,32 @@ class LMAnime :
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
super.setupPreferenceScreen(screen) // Quality preferences
|
||||
|
||||
ListPreference(screen.context).apply {
|
||||
key = PREF_LANG_KEY
|
||||
title = PREF_LANG_TITLE
|
||||
entries = PREF_LANG_ENTRIES
|
||||
entryValues = PREF_LANG_ENTRIES
|
||||
setDefaultValue(PREF_LANG_DEFAULT)
|
||||
summary = "%s"
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val selected = newValue as String
|
||||
val index = findIndexOfValue(selected)
|
||||
val entry = entryValues[index] as String
|
||||
preferences.edit().putString(key, entry).commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
screen.addListPreference(
|
||||
key = PREF_LANG_KEY,
|
||||
title = PREF_LANG_TITLE,
|
||||
entries = PREF_LANG_ENTRIES,
|
||||
entryValues = PREF_LANG_ENTRIES,
|
||||
default = PREF_LANG_DEFAULT,
|
||||
summary = "%s",
|
||||
)
|
||||
|
||||
MultiSelectListPreference(screen.context).apply {
|
||||
key = PREF_ALLOWED_LANGS_KEY
|
||||
title = PREF_ALLOWED_LANGS_TITLE
|
||||
entries = PREF_ALLOWED_LANGS_ENTRIES
|
||||
entryValues = PREF_ALLOWED_LANGS_ENTRIES
|
||||
setDefaultValue(PREF_ALLOWED_LANGS_DEFAULT)
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
preferences.edit().putStringSet(key, newValue as Set<String>).commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
screen.addSetPreference(
|
||||
key = PREF_ALLOWED_LANGS_KEY,
|
||||
title = PREF_ALLOWED_LANGS_TITLE,
|
||||
entries = PREF_ALLOWED_LANGS_ENTRIES,
|
||||
entryValues = PREF_ALLOWED_LANGS_ENTRIES,
|
||||
default = PREF_ALLOWED_LANGS_DEFAULT,
|
||||
summary = "",
|
||||
)
|
||||
}
|
||||
|
||||
private val SharedPreferences.langPref by preferences.delegate(PREF_LANG_KEY, PREF_LANG_DEFAULT)
|
||||
private val SharedPreferences.allowedLangsPref by preferences.delegate(PREF_ALLOWED_LANGS_KEY, PREF_ALLOWED_LANGS_DEFAULT)
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(prefQualityKey, prefQualityDefault)!!
|
||||
val lang = preferences.getString(PREF_LANG_KEY, PREF_LANG_DEFAULT)!!
|
||||
val quality = preferences.videoSortPref
|
||||
val lang = preferences.langPref
|
||||
return sortedWith(
|
||||
compareBy(
|
||||
{ it.quality.contains(quality) },
|
||||
@@ -99,7 +94,7 @@ class LMAnime :
|
||||
private const val PREF_LANG_KEY = "pref_language"
|
||||
private const val PREF_LANG_TITLE = "Preferred language"
|
||||
private const val PREF_LANG_DEFAULT = "English"
|
||||
private val PREF_LANG_ENTRIES = arrayOf(
|
||||
private val PREF_LANG_ENTRIES = listOf(
|
||||
"English",
|
||||
"Español",
|
||||
"Indonesian",
|
||||
|
||||
@@ -5,7 +5,6 @@ import aniyomi.lib.streamwishextractor.StreamWishExtractor
|
||||
import aniyomi.lib.vidhideextractor.VidHideExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class AnimeKhor :
|
||||
AnimeStream(
|
||||
@@ -15,9 +14,9 @@ class AnimeKhor :
|
||||
) {
|
||||
// ============================ Video Links =============================
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
val prefix = "$name - "
|
||||
when {
|
||||
return when {
|
||||
url.contains("ahvsh.com") || name.equals("streamhide", true) -> {
|
||||
VidHideExtractor(client, headers).videosFromUrl(url) { "$prefix$it" }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.animenosub
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import aniyomi.lib.streamwishextractor.StreamWishExtractor
|
||||
import aniyomi.lib.vidmolyextractor.VidMolyExtractor
|
||||
@@ -9,7 +9,8 @@ import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.VtubeExtracto
|
||||
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.WolfstreamExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import keiyoushi.utils.addListPreference
|
||||
import keiyoushi.utils.delegate
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
class Animenosub :
|
||||
@@ -30,9 +31,9 @@ class Animenosub :
|
||||
|
||||
// ============================ Video Links =============================
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
val prefix = "$name - "
|
||||
when {
|
||||
return when {
|
||||
listOf(
|
||||
"bysesayeveum",
|
||||
"filemoon",
|
||||
@@ -71,32 +72,32 @@ class Animenosub :
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
super.setupPreferenceScreen(screen) // Quality preferences
|
||||
|
||||
val videoTypePref = ListPreference(screen.context).apply {
|
||||
key = PREF_TYPE_KEY
|
||||
title = PREF_TYPE_TITLE
|
||||
entries = PREF_TYPE_VALUES
|
||||
entryValues = PREF_TYPE_VALUES
|
||||
setDefaultValue(PREF_TYPE_DEFAULT)
|
||||
summary = "%s"
|
||||
}
|
||||
val videoServerPref = ListPreference(screen.context).apply {
|
||||
key = PREF_SERVER_KEY
|
||||
title = PREF_SERVER_TITLE
|
||||
entries = PREF_SERVER_VALUES
|
||||
entryValues = PREF_SERVER_VALUES
|
||||
setDefaultValue(PREF_SERVER_DEFAULT)
|
||||
summary = "%s"
|
||||
}
|
||||
screen.addPreference(videoTypePref)
|
||||
screen.addPreference(videoServerPref)
|
||||
screen.addListPreference(
|
||||
key = PREF_TYPE_KEY,
|
||||
title = PREF_TYPE_TITLE,
|
||||
entries = PREF_TYPE_VALUES,
|
||||
entryValues = PREF_TYPE_VALUES,
|
||||
default = PREF_TYPE_DEFAULT,
|
||||
summary = "%s",
|
||||
)
|
||||
screen.addListPreference(
|
||||
key = PREF_SERVER_KEY,
|
||||
title = PREF_SERVER_TITLE,
|
||||
entries = PREF_SERVER_VALUES,
|
||||
entryValues = PREF_SERVER_VALUES,
|
||||
default = PREF_SERVER_DEFAULT,
|
||||
summary = "%s",
|
||||
)
|
||||
}
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
private val SharedPreferences.typePref by preferences.delegate(PREF_TYPE_KEY, PREF_TYPE_DEFAULT)
|
||||
private val SharedPreferences.serverPref by preferences.delegate(PREF_SERVER_KEY, PREF_SERVER_DEFAULT)
|
||||
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(prefQualityKey, prefQualityDefault)!!
|
||||
val type = preferences.getString(PREF_TYPE_KEY, PREF_TYPE_DEFAULT)!!
|
||||
val server = preferences.getString(PREF_SERVER_KEY, PREF_SERVER_DEFAULT)!!
|
||||
val quality = preferences.videoSortPref
|
||||
val type = preferences.typePref
|
||||
val server = preferences.serverPref
|
||||
return sortedWith(
|
||||
compareBy(
|
||||
{ it.quality.contains(type, ignoreCase = true) },
|
||||
@@ -110,12 +111,12 @@ class Animenosub :
|
||||
private const val PREF_TYPE_KEY = "preferred_type"
|
||||
private const val PREF_TYPE_TITLE = "Preferred Video Type"
|
||||
private const val PREF_TYPE_DEFAULT = "SUB"
|
||||
private val PREF_TYPE_VALUES = arrayOf("SUB", "RAW")
|
||||
private val PREF_TYPE_VALUES = listOf("SUB", "RAW")
|
||||
|
||||
private const val PREF_SERVER_KEY = "preferred_server"
|
||||
private const val PREF_SERVER_TITLE = "Preferred Video Server"
|
||||
private const val PREF_SERVER_DEFAULT = "Moon"
|
||||
private val PREF_SERVER_VALUES = arrayOf(
|
||||
private val PREF_SERVER_VALUES = listOf(
|
||||
"Moon",
|
||||
"StreamWish",
|
||||
"VidMoly",
|
||||
|
||||
@@ -11,15 +11,13 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import keiyoushi.utils.LazyMutable
|
||||
import keiyoushi.utils.UrlUtils
|
||||
import keiyoushi.utils.addSetPreference
|
||||
import keiyoushi.utils.addSwitchPreference
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import keiyoushi.utils.delegate
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import kotlin.getValue
|
||||
|
||||
class DonghuaStream :
|
||||
AnimeStream(
|
||||
@@ -27,8 +25,8 @@ class DonghuaStream :
|
||||
"DonghuaStream",
|
||||
"https://donghuastream.org",
|
||||
) {
|
||||
override val fetchFilters: Boolean
|
||||
get() = false
|
||||
|
||||
override val fetchFilters = false
|
||||
|
||||
// ============================ Manual Changes ==========================
|
||||
|
||||
@@ -46,11 +44,11 @@ class DonghuaStream :
|
||||
return GET(url)
|
||||
}
|
||||
|
||||
private var SharedPreferences.ignorePreview
|
||||
by LazyMutable { preferences.getBoolean(IGNORE_PREVIEW_KEY, IGNORE_PREVIEW_DEFAULT) }
|
||||
private val SharedPreferences.ignorePreview
|
||||
by preferences.delegate(IGNORE_PREVIEW_KEY, IGNORE_PREVIEW_DEFAULT)
|
||||
|
||||
private var SharedPreferences.enabledHosters
|
||||
by LazyMutable { preferences.getStringSet(PREF_HOSTER_KEY, PREF_HOSTER_DEFAULT)!! }
|
||||
by preferences.delegate(PREF_HOSTER_KEY, PREF_HOSTER_DEFAULT)
|
||||
|
||||
private companion object {
|
||||
private const val PREF_HOSTER_KEY = "dm_hoster_selection"
|
||||
@@ -72,22 +70,17 @@ class DonghuaStream :
|
||||
entries = INTERNAL_HOSTER_NAMES,
|
||||
entryValues = PREF_HOSTER_ENTRY_VALUES,
|
||||
default = PREF_HOSTER_DEFAULT,
|
||||
) {
|
||||
preferences.enabledHosters = it
|
||||
}
|
||||
)
|
||||
|
||||
screen.addSwitchPreference(
|
||||
key = IGNORE_PREVIEW_KEY,
|
||||
title = "Skip Preview episodes",
|
||||
summary = "",
|
||||
default = IGNORE_PREVIEW_DEFAULT,
|
||||
) {
|
||||
preferences.ignorePreview = it
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override val prefQualityValues = arrayOf("2160p", "1440p", "1080p", "720p", "480p", "360p")
|
||||
override val prefQualityEntries = prefQualityValues
|
||||
override val prefQualityValues = listOf("2160p", "1440p", "1080p", "720p", "480p", "360p")
|
||||
|
||||
override fun episodeListParse(response: Response): List<SEpisode> = super.episodeListParse(response)
|
||||
.filter { !it.name.contains("Preview", ignoreCase = true) || !preferences.ignorePreview }
|
||||
@@ -100,21 +93,19 @@ class DonghuaStream :
|
||||
|
||||
private val rumbleExtractor by lazy { RumbleExtractor(client, headers) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
val prefix = "$name - "
|
||||
return runBlocking {
|
||||
when {
|
||||
preferences.enabledHosters.contains("dailymotion") && url.contains("dailymotion") ->
|
||||
dailymotionExtractor.videosFromUrl(url, prefix = prefix)
|
||||
preferences.enabledHosters.contains("streamplay") && url.contains("streamplay") ->
|
||||
streamPlayExtractor.videosFromUrl(url, prefix = prefix)
|
||||
preferences.enabledHosters.contains("ok.ru") && url.contains("ok.ru") ->
|
||||
UrlUtils.fixUrl(url)?.let { okruExtractor.videosFromUrl(url = it, prefix = prefix) }
|
||||
?: emptyList()
|
||||
preferences.enabledHosters.contains("rumble") && url.contains("rumble") ->
|
||||
rumbleExtractor.videosFromUrl(url, prefix = prefix)
|
||||
else -> emptyList()
|
||||
}
|
||||
return when {
|
||||
preferences.enabledHosters.contains("dailymotion") && url.contains("dailymotion") ->
|
||||
dailymotionExtractor.videosFromUrl(url, prefix = prefix)
|
||||
preferences.enabledHosters.contains("streamplay") && url.contains("streamplay") ->
|
||||
streamPlayExtractor.videosFromUrl(url, prefix = prefix)
|
||||
preferences.enabledHosters.contains("ok.ru") && url.contains("ok.ru") ->
|
||||
UrlUtils.fixUrl(url)?.let { okruExtractor.videosFromUrl(url = it, prefix = prefix) }
|
||||
?: emptyList()
|
||||
preferences.enabledHosters.contains("rumble") && url.contains("rumble") ->
|
||||
rumbleExtractor.videosFromUrl(url, prefix = prefix)
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +114,7 @@ class DonghuaStream :
|
||||
private val qualityRegex by lazy { Regex("""(\d+)p""") }
|
||||
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(videoSortPrefKey, videoSortPrefDefault)!!
|
||||
val quality = preferences.videoSortPref
|
||||
return sortedWith(
|
||||
compareBy<Video>(
|
||||
{ it.quality.contains(quality, true) },
|
||||
|
||||
@@ -5,7 +5,6 @@ import aniyomi.lib.okruextractor.OkruExtractor
|
||||
import aniyomi.lib.streamwishextractor.StreamWishExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class LuciferDonghua :
|
||||
AnimeStream(
|
||||
@@ -21,9 +20,9 @@ class LuciferDonghua :
|
||||
private val dailymotionExtractor by lazy { DailymotionExtractor(client, headers) }
|
||||
private val filelionsExtractor by lazy { StreamWishExtractor(client, headers) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
val prefix = "$name - "
|
||||
when {
|
||||
return when {
|
||||
url.contains("ok.ru") -> okruExtractor.videosFromUrl(url, prefix = prefix)
|
||||
url.contains("dailymotion") -> dailymotionExtractor.videosFromUrl(url, prefix)
|
||||
url.contains("filelions") -> filelionsExtractor.videosFromUrl(url, videoNameGen = { quality -> "FileLions - $quality" })
|
||||
@@ -33,7 +32,7 @@ class LuciferDonghua :
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(videoSortPrefKey, videoSortPrefDefault)!!
|
||||
val quality = preferences.videoSortPref
|
||||
return sortedWith(
|
||||
compareBy(
|
||||
{ it.quality.contains(quality) },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package eu.kanade.tachiyomi.animeextension.es.animeytes
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import aniyomi.lib.burstcloudextractor.BurstCloudExtractor
|
||||
import aniyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
@@ -11,8 +11,9 @@ import aniyomi.lib.universalextractor.UniversalExtractor
|
||||
import aniyomi.lib.youruploadextractor.YourUploadExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import keiyoushi.utils.addListPreference
|
||||
import keiyoushi.utils.delegate
|
||||
import keiyoushi.utils.getPreferencesLazy
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class AnimeYTES :
|
||||
AnimeStream(
|
||||
@@ -22,14 +23,13 @@ class AnimeYTES :
|
||||
) {
|
||||
override val preferences by getPreferencesLazy()
|
||||
|
||||
companion object {
|
||||
private const val PREF_QUALITY_KEY = "preferred_quality"
|
||||
private const val PREF_QUALITY_DEFAULT = "1080"
|
||||
private val QUALITY_LIST = arrayOf("1080", "720", "480", "360")
|
||||
override val prefQualityDefault = "1080"
|
||||
override val prefQualityValues = listOf("1080", "720", "480", "360")
|
||||
|
||||
companion object {
|
||||
private const val PREF_SERVER_KEY = "preferred_server"
|
||||
private const val PREF_SERVER_DEFAULT = "Amazon"
|
||||
private val SERVER_LIST = arrayOf(
|
||||
private val SERVER_LIST = listOf(
|
||||
"YourUpload",
|
||||
"SendVid",
|
||||
"BurstCloud",
|
||||
@@ -50,21 +50,21 @@ class AnimeYTES :
|
||||
private val filemoonExtractor by lazy { FilemoonExtractor(client) }
|
||||
private val universalExtractor by lazy { UniversalExtractor(client) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
when (name) {
|
||||
"OK" -> okruExtractor.videosFromUrl(url)
|
||||
"Stream" -> streamtapeExtractor.videosFromUrl(url)
|
||||
"Send" -> sendvidExtractor.videosFromUrl(url)
|
||||
"Your" -> youruploadExtractor.videoFromUrl(url, headers)
|
||||
"Alpha" -> burstcloudExtractor.videoFromUrl(url, headers)
|
||||
"Moon" -> filemoonExtractor.videosFromUrl(url)
|
||||
else -> universalExtractor.videosFromUrl(url, headers)
|
||||
}
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> = when (name) {
|
||||
"OK" -> okruExtractor.videosFromUrl(url)
|
||||
"Stream" -> streamtapeExtractor.videosFromUrl(url)
|
||||
"Send" -> sendvidExtractor.videosFromUrl(url)
|
||||
"Your" -> youruploadExtractor.videoFromUrl(url, headers)
|
||||
"Alpha" -> burstcloudExtractor.videoFromUrl(url, headers)
|
||||
"Moon" -> filemoonExtractor.videosFromUrl(url)
|
||||
else -> universalExtractor.videosFromUrl(url, headers)
|
||||
}
|
||||
|
||||
private val SharedPreferences.serverPref by preferences.delegate(PREF_SERVER_KEY, PREF_SERVER_DEFAULT)
|
||||
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(PREF_QUALITY_KEY, PREF_QUALITY_DEFAULT)!!
|
||||
val server = preferences.getString(PREF_SERVER_KEY, PREF_SERVER_DEFAULT)!!
|
||||
val quality = preferences.videoSortPref
|
||||
val server = preferences.serverPref
|
||||
return this.sortedWith(
|
||||
compareBy(
|
||||
{ it.quality.contains(server, true) },
|
||||
@@ -75,36 +75,15 @@ class AnimeYTES :
|
||||
}
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
ListPreference(screen.context).apply {
|
||||
key = PREF_QUALITY_KEY
|
||||
title = "Preferred quality"
|
||||
entries = QUALITY_LIST
|
||||
entryValues = QUALITY_LIST
|
||||
setDefaultValue(PREF_QUALITY_DEFAULT)
|
||||
summary = "%s"
|
||||
super.setupPreferenceScreen(screen) // Quality preferences
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val selected = newValue as String
|
||||
val index = findIndexOfValue(selected)
|
||||
val entry = entryValues[index] as String
|
||||
preferences.edit().putString(key, entry).commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
|
||||
ListPreference(screen.context).apply {
|
||||
key = PREF_SERVER_KEY
|
||||
title = "Preferred server"
|
||||
entries = SERVER_LIST
|
||||
entryValues = SERVER_LIST
|
||||
setDefaultValue(PREF_SERVER_DEFAULT)
|
||||
summary = "%s"
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val selected = newValue as String
|
||||
val index = findIndexOfValue(selected)
|
||||
val entry = entryValues[index] as String
|
||||
preferences.edit().putString(key, entry).commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
screen.addListPreference(
|
||||
key = PREF_SERVER_KEY,
|
||||
title = "Preferred server",
|
||||
entries = SERVER_LIST,
|
||||
entryValues = SERVER_LIST,
|
||||
default = PREF_SERVER_DEFAULT,
|
||||
summary = "%s",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import aniyomi.lib.voeextractor.VoeExtractor
|
||||
import aniyomi.lib.youruploadextractor.YourUploadExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class Tiodonghua :
|
||||
AnimeStream(
|
||||
@@ -21,16 +20,13 @@ class Tiodonghua :
|
||||
private val youruploadExtractor by lazy { YourUploadExtractor(client) }
|
||||
private val mixdropExtractor by lazy { MixDropExtractor(client) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
when (name) {
|
||||
"Okru" -> okruExtractor.videosFromUrl(url)
|
||||
"Voe" -> voeExtractor.videosFromUrl(url)
|
||||
"YourUpload" -> youruploadExtractor.videoFromUrl(url, headers)
|
||||
"MixDrop" -> mixdropExtractor.videosFromUrl(url)
|
||||
else -> emptyList()
|
||||
}
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> = when (name) {
|
||||
"Okru" -> okruExtractor.videosFromUrl(url)
|
||||
"Voe" -> voeExtractor.videosFromUrl(url)
|
||||
"YourUpload" -> youruploadExtractor.videoFromUrl(url, headers)
|
||||
"MixDrop" -> mixdropExtractor.videosFromUrl(url)
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
override val fetchFilters: Boolean
|
||||
get() = false
|
||||
override val fetchFilters = false
|
||||
}
|
||||
|
||||
@@ -17,10 +17,8 @@ import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import keiyoushi.utils.parallelCatchingFlatMapBlocking
|
||||
import keiyoushi.utils.useAsJsoup
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Request
|
||||
@@ -76,11 +74,10 @@ class MyKdrama :
|
||||
}
|
||||
|
||||
// ============================ Video Links =============================
|
||||
override val prefQualityValues = arrayOf("1080p", "720p", "480p", "360p", "240p", "144p")
|
||||
override val prefQualityEntries = prefQualityValues
|
||||
override val prefQualityValues = listOf("1080p", "720p", "480p", "360p", "240p", "144p")
|
||||
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val doc = response.use { it.asJsoup() }
|
||||
val doc = response.useAsJsoup()
|
||||
return doc.select(videoListSelector()).parallelCatchingFlatMapBlocking { element ->
|
||||
val name = element.text()
|
||||
val url = getHosterUrl(element)
|
||||
@@ -101,14 +98,12 @@ class MyKdrama :
|
||||
private val doodExtractor by lazy { DoodExtractor(client) }
|
||||
private val vudeoExtractor by lazy { VudeoExtractor(client) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
when {
|
||||
"ok.ru" in url -> okruExtractor.videosFromUrl(url)
|
||||
"uqload" in url -> uqloadExtractor.videosFromUrl(url)
|
||||
"dood" in url || "doodstream" in url -> doodExtractor.videosFromUrl(url)
|
||||
"vudeo" in url -> vudeoExtractor.videosFromUrl(url)
|
||||
else -> emptyList()
|
||||
}
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> = when {
|
||||
"ok.ru" in url -> okruExtractor.videosFromUrl(url)
|
||||
"uqload" in url -> uqloadExtractor.videosFromUrl(url)
|
||||
"dood" in url || "doodstream" in url -> doodExtractor.videosFromUrl(url)
|
||||
"vudeo" in url -> vudeoExtractor.videosFromUrl(url)
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
|
||||
@@ -20,7 +20,7 @@ import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import keiyoushi.utils.tryParse
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Request
|
||||
import org.jsoup.nodes.Element
|
||||
@@ -32,6 +32,9 @@ class AnimeIndo :
|
||||
"https://animeindo.skin",
|
||||
) {
|
||||
|
||||
// ============================== Filters ============================== (fetch URL)
|
||||
override val animeListUrl = "$baseUrl/browse"
|
||||
|
||||
// ============================== Popular ===============================
|
||||
override fun popularAnimeRequest(page: Int) = GET("$baseUrl/browse?sort=view&page=$page")
|
||||
|
||||
@@ -47,7 +50,22 @@ class AnimeIndo :
|
||||
if (params.studios.isNotEmpty()) append(params.studios + "&")
|
||||
}
|
||||
|
||||
return GET("$baseUrl/browse?page=$page&title=$query&$multiString&status=${params.status}&type=${params.type}&order=${params.order}")
|
||||
val urlBuilder = baseUrl.toHttpUrl().newBuilder().apply {
|
||||
addPathSegment("browse")
|
||||
addQueryParameter("page", page.toString())
|
||||
if (query.isNotBlank()) addQueryParameter("title", query)
|
||||
if (params.status.isNotBlank()) addQueryParameter("status", params.status)
|
||||
if (params.type.isNotBlank()) addQueryParameter("type", params.type)
|
||||
if (params.order.isNotBlank()) addQueryParameter("order", params.order)
|
||||
}
|
||||
val url = urlBuilder.build().toString().let {
|
||||
if (multiString.isNotBlank()) {
|
||||
"$it&$multiString".removeSuffix("&")
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
return GET(url)
|
||||
}
|
||||
|
||||
override fun searchAnimeSelector() = "div.animepost > div > a"
|
||||
@@ -63,7 +81,7 @@ class AnimeIndo :
|
||||
// ============================== Filters ===============================
|
||||
override val filtersSelector = "div.filtersearch tbody > tr:not(:has(td.filter_title:contains(Search))) > td.filter_act"
|
||||
|
||||
override fun getFilterList(): AnimeFilterList = if (AnimeStreamFilters.filterInitialized()) {
|
||||
override fun getFilterList(): AnimeFilterList = if (AnimeStreamFilters.filterInitialized() && AnimeStreamFilters.filterElements.isNotEmpty()) {
|
||||
AnimeFilterList(
|
||||
OrderFilter(orderFilterText),
|
||||
StatusFilter(statusFilterText),
|
||||
@@ -93,7 +111,7 @@ class AnimeIndo :
|
||||
val num = ahref.text()
|
||||
name = "Episode $num"
|
||||
episode_number = num.trim().toFloatOrNull() ?: 0F
|
||||
date_upload = element.selectFirst("span.date")?.text().toDate()
|
||||
date_upload = element.selectFirst("span.date")?.text().let { dateFormatter.tryParse(it) }
|
||||
}
|
||||
|
||||
// ============================ Video Links =============================
|
||||
@@ -103,30 +121,28 @@ class AnimeIndo :
|
||||
private val yourUploadExtractor by lazy { YourUploadExtractor(client) }
|
||||
private val okruExtractor by lazy { OkruExtractor(client) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
with(name) {
|
||||
when {
|
||||
contains("streamtape") -> streamTapeExtractor.videoFromUrl(url)?.let(::listOf).orEmpty()
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> = with(name) {
|
||||
when {
|
||||
contains("streamtape") -> streamTapeExtractor.videoFromUrl(url)?.let(::listOf).orEmpty()
|
||||
|
||||
contains("mp4") -> mp4uploadExtractor.videosFromUrl(url, headers)
|
||||
contains("mp4") -> mp4uploadExtractor.videosFromUrl(url, headers)
|
||||
|
||||
contains("yourupload") -> yourUploadExtractor.videoFromUrl(url, headers)
|
||||
contains("yourupload") -> yourUploadExtractor.videoFromUrl(url, headers)
|
||||
|
||||
url.contains("ok.ru") -> okruExtractor.videosFromUrl(url)
|
||||
url.contains("ok.ru") -> okruExtractor.videosFromUrl(url)
|
||||
|
||||
contains("gdrive") -> {
|
||||
val gdriveUrl = when {
|
||||
baseUrl in url -> "https:" + url.toHttpUrl().queryParameter("data")!!
|
||||
else -> url
|
||||
}
|
||||
gdrivePlayerExtractor.videosFromUrl(gdriveUrl, "Gdrive", headers)
|
||||
contains("gdrive") -> {
|
||||
val gdriveUrl = when {
|
||||
baseUrl in url -> "https:" + url.toHttpUrl().queryParameter("data")!!
|
||||
else -> url
|
||||
}
|
||||
gdrivePlayerExtractor.videosFromUrl(gdriveUrl, "Gdrive", headers)
|
||||
}
|
||||
|
||||
else -> {
|
||||
// just to detect video hosts easily
|
||||
Log.i("AnimeIndo", "Unrecognized at getVideoList => Name -> $name || URL => $url")
|
||||
emptyList()
|
||||
}
|
||||
else -> {
|
||||
// just to detect video hosts easily
|
||||
Log.i("AnimeIndo", "Unrecognized at getVideoList => Name -> $name || URL => $url")
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,13 +40,14 @@ object AnimeIndoFilters {
|
||||
)
|
||||
}
|
||||
|
||||
private fun getPairListByIndex(index: Int) = filterElements.get(index)
|
||||
.select("ul > li, td > label")
|
||||
.map { element ->
|
||||
private fun getPairListByIndex(index: Int) = filterElements.getOrNull(index)
|
||||
?.select("ul > li, td > label")
|
||||
?.mapNotNull { element ->
|
||||
val key = element.text()
|
||||
val value = element.selectFirst("input")!!.attr("value")
|
||||
val value = element.selectFirst("input")?.attr("value") ?: return@mapNotNull null
|
||||
Pair(key, value)
|
||||
}.toTypedArray()
|
||||
}?.toTypedArray()
|
||||
?: arrayOf("" to "")
|
||||
|
||||
private val ORDER_LIST by lazy {
|
||||
getPairListByIndex(0)
|
||||
|
||||
@@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import keiyoushi.utils.tryParse
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Request
|
||||
import org.jsoup.nodes.Document
|
||||
@@ -49,11 +50,11 @@ class MiniOppai :
|
||||
}
|
||||
}
|
||||
element.selectFirst(".epl-sub")?.text()?.let { scanlator = it }
|
||||
date_upload = element.selectFirst(".epl-date")?.text().toDate()
|
||||
date_upload = element.selectFirst(".epl-date")?.text().let { dateFormatter.tryParse(it) }
|
||||
}
|
||||
|
||||
// ============================ Video Links =============================
|
||||
override fun getVideoList(url: String, name: String): List<Video> {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
return when {
|
||||
"gdriveplayer" in url -> {
|
||||
val playerUrl = buildString {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package eu.kanade.tachiyomi.animeextension.pl.desuonline
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import aniyomi.lib.googledriveextractor.GoogleDriveExtractor
|
||||
import aniyomi.lib.okruextractor.OkruExtractor
|
||||
@@ -8,7 +8,8 @@ import aniyomi.lib.sibnetextractor.SibnetExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.pl.desuonline.extractors.CDAExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import keiyoushi.utils.addListPreference
|
||||
import keiyoushi.utils.delegate
|
||||
import okhttp3.Response
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
@@ -35,8 +36,8 @@ class DesuOnline :
|
||||
private val sibnetExtractor by lazy { SibnetExtractor(client) }
|
||||
private val gdriveExtractor by lazy { GoogleDriveExtractor(client, headers) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
when {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
return when {
|
||||
url.contains("ok.ru") -> okruExtractor.videosFromUrl(url, name)
|
||||
|
||||
url.contains("cda.pl") -> cdaExtractor.videosFromUrl(url, name)
|
||||
@@ -44,7 +45,7 @@ class DesuOnline :
|
||||
url.contains("sibnet") -> sibnetExtractor.videosFromUrl(url, prefix = "$name - ")
|
||||
|
||||
url.contains("drive.google.com") -> {
|
||||
val id = Regex("[\\w-]{28,}").find(url)?.groupValues?.get(0) ?: return@runBlocking emptyList()
|
||||
val id = Regex("[\\w-]{28,}").find(url)?.groupValues?.get(0) ?: return emptyList()
|
||||
gdriveExtractor.videosFromUrl("https://drive.google.com/uc?id=$id", videoName = name)
|
||||
}
|
||||
|
||||
@@ -54,9 +55,11 @@ class DesuOnline :
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
|
||||
private val SharedPreferences.serverPref by preferences.delegate(prefServerKey, prefServerDefault)
|
||||
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
val quality = preferences.getString(videoSortPrefKey, videoSortPrefDefault)!!
|
||||
val server = preferences.getString(prefServerKey, prefServerDefault)!!
|
||||
val quality = preferences.videoSortPref
|
||||
val server = preferences.serverPref
|
||||
|
||||
return sortedWith(
|
||||
compareBy(
|
||||
@@ -72,20 +75,13 @@ class DesuOnline :
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
super.setupPreferenceScreen(screen) // Quality preferences
|
||||
|
||||
ListPreference(screen.context).apply {
|
||||
key = prefServerKey
|
||||
title = "Preferred server"
|
||||
entries = arrayOf("CDA", "Sibnet", "Google Drive", "ok.ru")
|
||||
entryValues = arrayOf("CDA", "sibnet", "gd", "okru")
|
||||
setDefaultValue(prefServerDefault)
|
||||
summary = "%s"
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val selected = newValue as String
|
||||
val index = findIndexOfValue(selected)
|
||||
val entry = entryValues[index] as String
|
||||
preferences.edit().putString(key, entry).commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
screen.addListPreference(
|
||||
key = prefServerKey,
|
||||
title = "Preferred server",
|
||||
entries = listOf("CDA", "Sibnet", "Google Drive", "ok.ru"),
|
||||
entryValues = listOf("CDA", "sibnet", "gd", "okru"),
|
||||
default = prefServerDefault,
|
||||
summary = "%s",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,7 @@ class DarkMahou :
|
||||
}
|
||||
|
||||
// ============================ Video Links =============================
|
||||
override val prefQualityValues = arrayOf("1080p", "720p", "480p", "360p", "240p")
|
||||
override val prefQualityEntries = prefQualityValues
|
||||
override val prefQualityValues = listOf("1080p", "720p", "480p", "360p", "240p")
|
||||
|
||||
private val darkmahouExtractor by lazy { DarkMahouExtractor(client, headers) }
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import eu.kanade.tachiyomi.animeextension.sr.animebalkan.extractors.MailRuExtrac
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import keiyoushi.utils.useAsJsoup
|
||||
import org.jsoup.nodes.Element
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
@@ -25,7 +25,7 @@ class AnimeBalkan :
|
||||
}
|
||||
|
||||
// ============================ Video Links =============================
|
||||
override fun getHosterUrl(element: Element): String {
|
||||
override suspend fun getHosterUrl(element: Element): String {
|
||||
if (element.text().contains("Server AB")) {
|
||||
return element.attr("value")
|
||||
}
|
||||
@@ -37,8 +37,8 @@ class AnimeBalkan :
|
||||
private val mailruExtractor by lazy { MailRuExtractor(client, headers) }
|
||||
private val okruExtractor by lazy { OkruExtractor(client) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
when {
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> {
|
||||
return when {
|
||||
"Server OK" in name || "ok.ru" in url -> okruExtractor.videosFromUrl(url)
|
||||
|
||||
"Server Ru" in name || "mail.ru" in url -> mailruExtractor.videosFromUrl(url)
|
||||
@@ -57,9 +57,9 @@ class AnimeBalkan :
|
||||
}
|
||||
|
||||
"Server AB" in name && baseUrl in url -> {
|
||||
val doc = client.newCall(GET(url)).execute().asJsoup()
|
||||
val doc = client.newCall(GET(url)).awaitSuccess().useAsJsoup()
|
||||
val videoUrl = doc.selectFirst("source")?.attr("src")
|
||||
?: return@runBlocking emptyList()
|
||||
?: return emptyList()
|
||||
listOf(Video(videoUrl, "Server AB - Default", videoUrl))
|
||||
}
|
||||
|
||||
@@ -67,6 +67,5 @@ class AnimeBalkan :
|
||||
}
|
||||
}
|
||||
|
||||
override val prefQualityValues = arrayOf("1080p", "720p", "480p", "360p", "240p")
|
||||
override val prefQualityEntries = prefQualityValues
|
||||
override val prefQualityValues = listOf("1080p", "720p", "480p", "360p", "240p")
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Request
|
||||
@@ -97,34 +96,29 @@ class AsyaAnimeleri :
|
||||
override val episodePrefix = "Bölüm"
|
||||
|
||||
// ============================ Video Links =============================
|
||||
override val prefQualityValues = arrayOf("1080p", "720p", "480p", "360p", "240p", "144p")
|
||||
override val prefQualityEntries = prefQualityValues
|
||||
override val prefQualityValues = listOf("1080p", "720p", "480p", "360p", "240p", "144p")
|
||||
|
||||
private val vkExtractor by lazy { VkExtractor(client, headers) }
|
||||
private val okruExtractor by lazy { OkruExtractor(client) }
|
||||
private val sibnetExtractor by lazy { SibnetExtractor(client) }
|
||||
private val gdrivePlayerExtractor by lazy { GdrivePlayerExtractor(client) }
|
||||
private val doodExtractor by lazy { DoodExtractor(client) }
|
||||
// private val dailyExtractor by lazy { DailymotionExtractor(client, headers) }
|
||||
|
||||
override fun getVideoList(url: String, name: String): List<Video> = runBlocking {
|
||||
when (name.lowercase().trim()) {
|
||||
"vk" -> vkExtractor.videosFromUrl(url)
|
||||
override suspend fun getVideoList(url: String, name: String): List<Video> = when (name.lowercase().trim()) {
|
||||
"vk" -> vkExtractor.videosFromUrl(url)
|
||||
|
||||
"ok.ru" -> okruExtractor.videosFromUrl(url)
|
||||
"ok.ru" -> okruExtractor.videosFromUrl(url)
|
||||
|
||||
"sibnet" -> sibnetExtractor.videosFromUrl(url)
|
||||
"sibnet" -> sibnetExtractor.videosFromUrl(url)
|
||||
|
||||
// "daily" -> dailyExtractor.videosFromUrl(url)
|
||||
"dood", "doodstream" -> doodExtractor.videoFromUrl(url)?.let(::listOf) ?: emptyList()
|
||||
"dood", "doodstream" -> doodExtractor.videoFromUrl(url)?.let(::listOf) ?: emptyList()
|
||||
|
||||
"gdrive" -> {
|
||||
val newUrl = "https://gdriveplayer.to/embed2.php?link=$url"
|
||||
gdrivePlayerExtractor.videosFromUrl(newUrl, "Gdrive", headers)
|
||||
}
|
||||
|
||||
else -> emptyList()
|
||||
"gdrive" -> {
|
||||
val newUrl = "https://gdriveplayer.to/embed2.php?link=$url"
|
||||
gdrivePlayerExtractor.videosFromUrl(newUrl, "Gdrive", headers)
|
||||
}
|
||||
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
|
||||
@@ -13,7 +13,8 @@ import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import keiyoushi.utils.tryParse
|
||||
import keiyoushi.utils.useAsJsoup
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Request
|
||||
@@ -119,12 +120,12 @@ class TRAnimeCI :
|
||||
name = "Bölüm $epNum"
|
||||
episode_number = epNum.toFloat()
|
||||
|
||||
date_upload = element.selectFirst(".epl-date")?.text().toDate()
|
||||
date_upload = element.selectFirst(".epl-date")?.text().let { dateFormatter.tryParse(it) }
|
||||
}
|
||||
|
||||
// ============================ Video Links =============================
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val doc = response.asJsoup()
|
||||
val doc = response.useAsJsoup()
|
||||
val script = doc.selectFirst("script:containsData(let video_source)")!!.data()
|
||||
return script.substringAfter("[").substringBefore("]")
|
||||
.split("{")
|
||||
|
||||
Reference in New Issue
Block a user