Skip to content

Commit

Permalink
Merge branch 'aniyomiorg:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
willyreza authored Nov 7, 2023
2 parents 58e8907 + 210bd64 commit 60d1929
Show file tree
Hide file tree
Showing 10 changed files with 413 additions and 152 deletions.
3 changes: 2 additions & 1 deletion multisrc/overrides/dooplay/cinemathek/additional.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ dependencies {
implementation(project(':lib-filemoon-extractor'))
implementation(project(':lib-dood-extractor'))
implementation(project(':lib-streamlare-extractor'))
implementation("dev.datlag.jsunpacker:jsunpacker:1.0.1")
implementation(project(':lib-streamtape-extractor'))
implementation(project(':lib-streamwish-extractor'))
}
57 changes: 37 additions & 20 deletions multisrc/overrides/dooplay/cinemathek/src/Cinemathek.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,38 @@ 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",
"Cinemathek",
"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")
Expand All @@ -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()
Expand All @@ -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("ds2play") || url.contains("https://doo")) && hosterSelection.contains("dood") -> {
doodExtractor.videosFromUrl(url)
}
url.contains("https://dooood") && hosterSelection.contains("dood") -> {
DoodExtractor(client).videosFromUrl(url)
url.contains("streamtape") && hosterSelection.contains("stape") -> {
streamtapeExtractor.videosFromUrl(url)
}
url.contains("https://streamhide") && hosterSelection.contains("shide") -> {
StreamHideExtractor(client).videosFromUrl(url)
(url.contains("filelions") || url.contains("streamwish")) && hosterSelection.contains("swish") -> {
streamwishExtractor.videosFromUrl(url)
}
else -> null
}
Expand Down Expand Up @@ -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"
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class DooPlayGenerator : ThemeSourceGenerator {
SingleLang("AnimeSAGA", "https://www.animesaga.in", "hi", isNsfw = false, overrideVersionCode = 7),
SingleLang("AnimesFox BR", "https://animesfox.net", "pt-BR", isNsfw = false, overrideVersionCode = 2),
SingleLang("Animes House", "https://animeshouse.net", "pt-BR", isNsfw = false, overrideVersionCode = 7),
SingleLang("Cinemathek", "https://cinemathek.net", "de", isNsfw = true, overrideVersionCode = 16),
SingleLang("Cinemathek", "https://cinemathek.net", "de", isNsfw = true, overrideVersionCode = 17),
SingleLang("DonghuaX", "https://donghuax.com", "pt-BR", isNsfw = false, overrideVersionCode = 1),
SingleLang("GoAnimes", "https://goanimes.net", "pt-BR", isNsfw = true, overrideVersionCode = 5),
SingleLang("JetAnime", "https://ssl.jetanimes.com", "fr", isNsfw = false, overrideVersionCode = 2),
Expand Down
2 changes: 1 addition & 1 deletion src/en/superstream/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ext {
extName = 'SuperStream'
pkgNameSuffix = 'en.superstream'
extClass = '.SuperStream'
extVersionCode = 9
extVersionCode = 10
libVersion = '13'
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ class SuperStream : ConfigurableAnimeSource, AnimeHttpSource() {

override val name = "SuperStream"

override val baseUrl by lazy { preferences.getString("preferred_domain", superStreamAPI.apiUrl)!! }

override val lang = "en"

override val supportsLatest = true
Expand All @@ -37,6 +35,8 @@ class SuperStream : ConfigurableAnimeSource, AnimeHttpSource() {

private val superStreamAPI = SuperStreamAPI(json)

override val baseUrl = superStreamAPI.apiUrl

override val client: OkHttpClient = network.cloudflareClient

private val preferences: SharedPreferences by lazy {
Expand Down Expand Up @@ -137,7 +137,7 @@ class SuperStream : ConfigurableAnimeSource, AnimeHttpSource() {
override fun searchAnimeParse(response: Response) = throw Exception("not used")

override fun fetchAnimeDetails(anime: SAnime): Observable<SAnime> {
val data = superStreamAPI.load(anime.url, true)
val data = superStreamAPI.load(anime.url)
val ani = SAnime.create()
val (movie, seriesData) = data
val (detail, _) = seriesData
Expand Down Expand Up @@ -192,21 +192,6 @@ class SuperStream : ConfigurableAnimeSource, AnimeHttpSource() {
override fun animeDetailsParse(response: Response) = throw Exception("not used")

override fun setupPreferenceScreen(screen: PreferenceScreen) {
val domainPref = ListPreference(screen.context).apply {
key = "preferred_domain"
title = "Preferred domain (requires app restart)"
entries = arrayOf("Default")
entryValues = arrayOf(superStreamAPI.apiUrl)
setDefaultValue(superStreamAPI.apiUrl)
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()
}
}
val videoQualityPref = ListPreference(screen.context).apply {
key = "preferred_quality"
title = "Preferred quality"
Expand All @@ -222,7 +207,6 @@ class SuperStream : ConfigurableAnimeSource, AnimeHttpSource() {
preferences.edit().putString(key, entry).commit()
}
}
screen.addPreference(domainPref)
screen.addPreference(videoQualityPref)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,6 @@ import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.Track
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.POST
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonPrimitive
Expand Down Expand Up @@ -815,7 +814,7 @@ class SuperStreamAPI(val json: Json) {
}
}

private fun queryApi(query: String, altApi: Boolean = false): Response {
private fun queryApi(query: String): Response {
val encryptedQuery = CipherUtils.encrypt(query, key, iv)!!
val appKeyHash = CipherUtils.md5(appKey)!!
val newBody =
Expand All @@ -837,15 +836,14 @@ class SuperStreamAPI(val json: Json) {
.add("medium", "Website&token$token")
.build()
try {
val url = if (altApi) secondApiUrl else thirdApiUrl
return client.newCall(POST(url, headers = headers, body = formData)).execute()
return client.newCall(POST(apiUrl, headers = headers, body = formData)).execute()
} catch (e: Exception) {
throw Exception("Query Failed\n$e")
}
}

private inline fun <reified T : Any> queryApiParsed(query: String, altApi: Boolean = false): T {
return parseJson(queryApi(query, altApi).body.string())
private inline fun <reified T : Any> queryApiParsed(query: String): T {
return parseJson(queryApi(query).body.string())
}

private val unixTime: Long
Expand All @@ -864,13 +862,7 @@ class SuperStreamAPI(val json: Json) {
// Free Tibet, The Tienanmen Square protests of 1989
private val iv = base64Decode("d0VpcGhUbiE=")
private val key = base64Decode("MTIzZDZjZWRmNjI2ZHk1NDIzM2FhMXc2")
private val ip = base64Decode("aHR0cHM6Ly8xNTIuMzIuMTQ5LjE2MA==")
val apiUrl = "$ip${base64Decode("L2FwaS9hcGlfY2xpZW50L2luZGV4Lw==")}"

// Thanks @Blatzar and his dream from cloudstream for the secondurl
private val secondApiUrl =
base64Decode("aHR0cHM6Ly9tYnBhcGkuc2hlZ3UubmV0L2FwaS9hcGlfY2xpZW50L2luZGV4Lw==")
private val thirdApiUrl = base64Decode("aHR0cHM6Ly9zaG93Ym94LnNoZWd1Lm5ldC9hcGkvYXBpX2NsaWVudC9pbmRleC8=")
val apiUrl = base64Decode("aHR0cHM6Ly9zaG93Ym94LnNoZWd1Lm5ldC9hcGkvYXBpX2NsaWVudC9pbmRleC8=")
private val appKey = base64Decode("bW92aWVib3g=")
private val appId = base64Decode("Y29tLnRkby5zaG93Ym94")

Expand Down Expand Up @@ -940,13 +932,13 @@ class SuperStreamAPI(val json: Json) {
val apiQuery =
// Originally 8 pagelimit
"""{"childmode":"$hideNsfw","app_version":"11.5","appid":"$appId","module":"Search3","channel":"Website","page":"$page","lang":"en","type":"all","keyword":"$query","pagelimit":"20","expired_date":"${getExpiryDate()}","platform":"android"}"""
val searchResponse = parseJson<MainData>(queryApi(apiQuery, true).body.string()).data.mapNotNull {
val searchResponse = parseJson<MainData>(queryApi(apiQuery).body.string()).data.mapNotNull {
it.toSearchResponse()
}
return searchResponse
}

fun load(url: String, altApi: Boolean = false): Pair<MovieData?, Pair<SeriesData?, List<SeriesEpisode>?>> {
fun load(url: String): Pair<MovieData?, Pair<SeriesData?, List<SeriesEpisode>?>> {
val loadData = parseJson<LoadData>(url)
// val module = if(type === "TvType.Movie") "Movie_detail" else "*tv series module*"

Expand All @@ -955,14 +947,14 @@ class SuperStreamAPI(val json: Json) {
if (isMovie) { // 1 = Movie
val apiQuery =
"""{"childmode":"$hideNsfw","uid":"","app_version":"11.5","appid":"$appId","module":"Movie_detail","channel":"Website","mid":"${loadData.id}","lang":"en","expired_date":"${getExpiryDate()}","platform":"android","oss":"","group":""}"""
val data = queryApiParsed<MovieDataProp>(apiQuery, altApi).data
val data = queryApiParsed<MovieDataProp>(apiQuery).data
?: throw RuntimeException("API error")

return Pair(data, Pair(null, null))
} else { // 2 Series
val apiQuery =
"""{"childmode":"$hideNsfw","uid":"","app_version":"11.5","appid":"$appId","module":"TV_detail_1","display_all":"1","channel":"Website","lang":"en","expired_date":"${getExpiryDate()}","platform":"android","tid":"${loadData.id}"}"""
val data = queryApiParsed<SeriesDataProp>(apiQuery, altApi).data
val data = queryApiParsed<SeriesDataProp>(apiQuery).data
?: throw RuntimeException("API error")

val episodes = data.season.mapNotNull {
Expand Down
2 changes: 1 addition & 1 deletion src/id/oploverz/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ext {
extName = 'Oploverz'
pkgNameSuffix = 'id.oploverz'
extClass = '.Oploverz'
extVersionCode = 17
extVersionCode = 18
libVersion = '13'
}

Expand Down
Loading

0 comments on commit 60d1929

Please sign in to comment.