|
|
|
@ -3,19 +3,22 @@ package eu.kanade.tachiyomi.animeextension.de.cinemathek
|
|
|
|
|
import androidx.preference.ListPreference
|
|
|
|
|
import androidx.preference.MultiSelectListPreference
|
|
|
|
|
import androidx.preference.PreferenceScreen
|
|
|
|
|
import eu.kanade.tachiyomi.animeextension.de.cinemathek.extractors.StreamHideExtractor
|
|
|
|
|
import eu.kanade.tachiyomi.animesource.model.Video
|
|
|
|
|
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
|
|
|
|
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
|
|
|
|
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
|
|
|
|
|
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
|
|
|
|
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
|
|
|
|
|
import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay
|
|
|
|
|
import eu.kanade.tachiyomi.network.GET
|
|
|
|
|
import eu.kanade.tachiyomi.util.asJsoup
|
|
|
|
|
import okhttp3.Request
|
|
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
|
import kotlinx.coroutines.async
|
|
|
|
|
import kotlinx.coroutines.awaitAll
|
|
|
|
|
import kotlinx.coroutines.runBlocking
|
|
|
|
|
import okhttp3.Response
|
|
|
|
|
import org.jsoup.nodes.Document
|
|
|
|
|
import org.jsoup.nodes.Element
|
|
|
|
|
import uy.kohesive.injekt.api.get
|
|
|
|
|
|
|
|
|
|
class Cinemathek : DooPlay(
|
|
|
|
|
"de",
|
|
|
|
@ -23,15 +26,15 @@ class Cinemathek : DooPlay(
|
|
|
|
|
"https://cinemathek.net",
|
|
|
|
|
) {
|
|
|
|
|
// ============================== Popular ===============================
|
|
|
|
|
override fun popularAnimeSelector(): String = "article.movies div.poster"
|
|
|
|
|
override fun popularAnimeSelector() = "article.movies div.poster"
|
|
|
|
|
|
|
|
|
|
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/filme/page/$page/")
|
|
|
|
|
override fun popularAnimeRequest(page: Int) = GET("$baseUrl/filme/page/$page/")
|
|
|
|
|
|
|
|
|
|
override fun popularAnimeNextPageSelector() = latestUpdatesNextPageSelector()
|
|
|
|
|
|
|
|
|
|
// =============================== Latest ===============================
|
|
|
|
|
override fun latestUpdatesNextPageSelector(): String = "#nextpagination"
|
|
|
|
|
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/episoden/page/$page")
|
|
|
|
|
override fun latestUpdatesNextPageSelector() = "#nextpagination"
|
|
|
|
|
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/episoden/page/$page")
|
|
|
|
|
|
|
|
|
|
// =========================== Anime Details ============================
|
|
|
|
|
override val additionalInfoItems = listOf("Original", "Start", "Staffeln", "letzte", "Episoden")
|
|
|
|
@ -46,9 +49,9 @@ class Cinemathek : DooPlay(
|
|
|
|
|
override fun videoListParse(response: Response): List<Video> {
|
|
|
|
|
val players = response.use { it.asJsoup().select("ul#playeroptionsul li") }
|
|
|
|
|
val hosterSelection = preferences.getStringSet(PREF_HOSTER_SELECTION_KEY, PREF_HOSTER_SELECTION_DEFAULT)!!
|
|
|
|
|
return players.mapNotNull { player ->
|
|
|
|
|
return players.parallelMapNotNull { player ->
|
|
|
|
|
runCatching {
|
|
|
|
|
val url = getPlayerUrl(player).ifEmpty { return@mapNotNull null }
|
|
|
|
|
val url = getPlayerUrl(player).ifEmpty { return@parallelMapNotNull null }
|
|
|
|
|
getPlayerVideos(url, hosterSelection)
|
|
|
|
|
}.getOrNull()
|
|
|
|
|
}.flatten()
|
|
|
|
@ -61,26 +64,35 @@ class Cinemathek : DooPlay(
|
|
|
|
|
if (num == "trailer") return ""
|
|
|
|
|
return client.newCall(GET("$baseUrl/wp-json/dooplayer/v2/$id/$type/$num"))
|
|
|
|
|
.execute()
|
|
|
|
|
.body.string()
|
|
|
|
|
.use { it.body.string() }
|
|
|
|
|
.substringAfter("\"embed_url\":\"")
|
|
|
|
|
.substringBefore("\",")
|
|
|
|
|
.replace("\\", "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private val streamlareExtractor by lazy { StreamlareExtractor(client) }
|
|
|
|
|
private val filemoonExtractor by lazy { FilemoonExtractor(client) }
|
|
|
|
|
private val doodExtractor by lazy { DoodExtractor(client) }
|
|
|
|
|
private val streamtapeExtractor by lazy { StreamTapeExtractor(client) }
|
|
|
|
|
private val streamwishExtractor by lazy { StreamWishExtractor(client, headers) }
|
|
|
|
|
|
|
|
|
|
private fun getPlayerVideos(url: String, hosterSelection: Set<String>): List<Video>? {
|
|
|
|
|
return when {
|
|
|
|
|
url.contains("https://streamlare.com") && hosterSelection.contains("slare") -> {
|
|
|
|
|
StreamlareExtractor(client).videosFromUrl(url)
|
|
|
|
|
streamlareExtractor.videosFromUrl(url)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
url.contains("https://filemoon") && hosterSelection.contains("fmoon") -> {
|
|
|
|
|
FilemoonExtractor(client).videosFromUrl(url)
|
|
|
|
|
filemoonExtractor.videosFromUrl(url)
|
|
|
|
|
}
|
|
|
|
|
url.contains("https://dooood") && hosterSelection.contains("dood") -> {
|
|
|
|
|
DoodExtractor(client).videosFromUrl(url)
|
|
|
|
|
(url.contains("ds2play") || url.contains("https://doo")) && hosterSelection.contains("dood") -> {
|
|
|
|
|
doodExtractor.videosFromUrl(url)
|
|
|
|
|
}
|
|
|
|
|
url.contains("https://streamhide") && hosterSelection.contains("shide") -> {
|
|
|
|
|
StreamHideExtractor(client).videosFromUrl(url)
|
|
|
|
|
url.contains("streamtape") && hosterSelection.contains("stape") -> {
|
|
|
|
|
streamtapeExtractor.videosFromUrl(url)
|
|
|
|
|
}
|
|
|
|
|
(url.contains("filelions") || url.contains("streamwish")) && hosterSelection.contains("swish") -> {
|
|
|
|
|
streamwishExtractor.videosFromUrl(url)
|
|
|
|
|
}
|
|
|
|
|
else -> null
|
|
|
|
|
}
|
|
|
|
@ -151,17 +163,22 @@ class Cinemathek : DooPlay(
|
|
|
|
|
).reversed()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private inline fun <A, B> Iterable<A>.parallelMapNotNull(crossinline f: suspend (A) -> B?): List<B> =
|
|
|
|
|
runBlocking {
|
|
|
|
|
map { async(Dispatchers.Default) { f(it) } }.awaitAll().filterNotNull()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
private const val PREF_HOSTER_KEY = "preferred_hoster"
|
|
|
|
|
private const val PREF_HOSTER_TITLE = "Standard-Hoster"
|
|
|
|
|
private const val PREF_HOSTER_DEFAULT = "https://viewsb.com"
|
|
|
|
|
private val PREF_HOSTER_ENTRIES = arrayOf("Streamlare", "Filemoon", "DoodStream", "StreamHide")
|
|
|
|
|
private val PREF_HOSTER_VALUES = arrayOf("https://streamlare", "https://viewsb.com", "https://filemoon", "https://dooood", "https://streamhide")
|
|
|
|
|
private const val PREF_HOSTER_DEFAULT = "https://filemoon"
|
|
|
|
|
private val PREF_HOSTER_ENTRIES = arrayOf("Streamlare", "Filemoon", "DoodStream", "StreamTape", "StreamWish/Filelions")
|
|
|
|
|
private val PREF_HOSTER_VALUES = arrayOf("https://streamlare", "https://filemoon", "https://doo", "https://streamtape", "https://streamwish")
|
|
|
|
|
|
|
|
|
|
private const val PREF_HOSTER_SELECTION_KEY = "hoster_selection"
|
|
|
|
|
private const val PREF_HOSTER_SELECTION_TITLE = "Hoster auswählen"
|
|
|
|
|
private val PREF_HOSTER_SELECTION_ENTRIES = PREF_HOSTER_ENTRIES
|
|
|
|
|
private val PREF_HOSTER_SELECTION_VALUES = arrayOf("slare", "fmoon", "dood", "shide")
|
|
|
|
|
private val PREF_HOSTER_SELECTION_VALUES = arrayOf("slare", "fmoon", "dood", "stape", "swish")
|
|
|
|
|
private val PREF_HOSTER_SELECTION_DEFAULT = PREF_HOSTER_SELECTION_VALUES.toSet()
|
|
|
|
|
|
|
|
|
|
private const val PREF_QUALITY_KEY = "preferred_quality"
|
|
|
|
|