fix(ar/Tuktukcinema): refactor, fix and adding more servers (#1882)
This commit is contained in:
@ -5,13 +5,16 @@ ext {
|
|||||||
extName = 'توك توك سينما'
|
extName = 'توك توك سينما'
|
||||||
pkgNameSuffix = 'ar.tuktukcinema'
|
pkgNameSuffix = 'ar.tuktukcinema'
|
||||||
extClass = '.Tuktukcinema'
|
extClass = '.Tuktukcinema'
|
||||||
extVersionCode = 6
|
extVersionCode = 7
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(':lib-okru-extractor'))
|
implementation(project(':lib-okru-extractor'))
|
||||||
implementation(project(':lib-dood-extractor'))
|
implementation(project(':lib-dood-extractor'))
|
||||||
|
implementation(project(':lib-streamtape-extractor'))
|
||||||
|
implementation(project(':lib-vidbom-extractor'))
|
||||||
|
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
@ -6,7 +6,8 @@ import android.widget.Toast
|
|||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.ar.tuktukcinema.extractors.MoshahdaExtractor
|
import eu.kanade.tachiyomi.animeextension.ar.tuktukcinema.extractors.UQLoadExtractor
|
||||||
|
import eu.kanade.tachiyomi.animeextension.ar.tuktukcinema.extractors.UpStreamExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
@ -14,9 +15,16 @@ import eu.kanade.tachiyomi.animesource.model.SAnime
|
|||||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||||
|
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.vidbomextractor.VidBomExtractor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.Headers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.awaitAll
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
@ -132,29 +140,39 @@ class Tuktukcinema : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
override fun videoListParse(response: Response): List<Video> {
|
override fun videoListParse(response: Response): List<Video> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val videos = mutableListOf<Video>()
|
return document.select(videoListSelector()).parallelMap {
|
||||||
document.select(videoListSelector()).forEach { server ->
|
runCatching { extractVideos(it.attr("data-link")) }.getOrElse { emptyList() }
|
||||||
val link = server.attr("data-link")
|
}.flatten()
|
||||||
if (link.contains("moshahda")) {
|
}
|
||||||
val refererHeaders = Headers.headersOf("referer", response.request.url.toString())
|
private inline fun <A, B> Iterable<A>.parallelMap(crossinline f: suspend (A) -> B): List<B> =
|
||||||
val videosFromURL = MoshahdaExtractor(client).videosFromUrl(link, refererHeaders)
|
runBlocking {
|
||||||
videos.addAll(videosFromURL)
|
map { async(Dispatchers.Default) { f(it) } }.awaitAll()
|
||||||
}
|
|
||||||
/* else if (link.contains("ok")) {
|
|
||||||
val videosFromURL = OkruExtractor(client).videosFromUrl(link)
|
|
||||||
videos.addAll(videosFromURL)
|
|
||||||
} else if (server.text().contains("vidbom", ignoreCase = true) or server.text().contains("vidshare", ignoreCase = true)) {
|
|
||||||
val videosFromURL = VidBomExtractor(client).videosFromUrl(link)
|
|
||||||
videos.addAll(videosFromURL)
|
|
||||||
} else if (server.text().contains("dood", ignoreCase = true)) {
|
|
||||||
val videosFromURL = DoodExtractor(client).videoFromUrl(link)
|
|
||||||
if (videosFromURL != null) videos.add(videosFromURL)
|
|
||||||
} else if (server.text().contains("uqload", ignoreCase = true)) {
|
|
||||||
val videosFromURL = UQLoadExtractor(client).videoFromUrl(link, "Uqload mirror")
|
|
||||||
if (videosFromURL != null) videos.add(videosFromURL)
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
return videos
|
|
||||||
|
private fun extractVideos(url: String): List<Video> {
|
||||||
|
return when {
|
||||||
|
url.contains("ok") -> {
|
||||||
|
OkruExtractor(client).videosFromUrl(url)
|
||||||
|
}
|
||||||
|
VIDBOM_REGEX.containsMatchIn(url) -> {
|
||||||
|
val finalUrl = VIDBOM_REGEX.find(url)!!.groupValues[0]
|
||||||
|
VidBomExtractor(client).videosFromUrl("https://www.$finalUrl")
|
||||||
|
}
|
||||||
|
DOOD_REGEX.containsMatchIn(url) -> {
|
||||||
|
val finalUrl = DOOD_REGEX.find(url)!!.groupValues[0]
|
||||||
|
DoodExtractor(client).videoFromUrl("https://www.$finalUrl", "Dood mirror", false)?.let(::listOf)
|
||||||
|
}
|
||||||
|
url.contains("uqload") -> {
|
||||||
|
UQLoadExtractor(client).videoFromUrl(url, "Uqload mirror")?.let(::listOf)
|
||||||
|
}
|
||||||
|
url.contains("tape") -> {
|
||||||
|
StreamTapeExtractor(client).videoFromUrl(url)?.let(::listOf)
|
||||||
|
}
|
||||||
|
url.contains("upstream", ignoreCase = true) -> {
|
||||||
|
UpStreamExtractor(client).videoFromUrl(url.replace("//","//www."))
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
} ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun List<Video>.sort(): List<Video> {
|
override fun List<Video>.sort(): List<Video> {
|
||||||
@ -317,4 +335,9 @@ class Tuktukcinema : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
screen.addPreference(defaultDomain)
|
screen.addPreference(defaultDomain)
|
||||||
screen.addPreference(videoQualityPref)
|
screen.addPreference(videoQualityPref)
|
||||||
}
|
}
|
||||||
|
companion object {
|
||||||
|
private val VIDBOM_REGEX = Regex("(?:v[aie]d[bp][aoe]?m|myvii?d|govad|segavid|v[aei]{1,2}dshar[er]?)\\.(?:com|net|org|xyz)(?::\\d+)?/(?:embed[/-])?([A-Za-z0-9]+).html")
|
||||||
|
private val DOOD_REGEX = Regex("(do*d(?:stream)?\\.(?:com?|watch|to|s[ho]|cx|la|w[sf]|pm|re|yt|stream))/[de]/([0-9a-zA-Z]+)")
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.animeextension.ar.tuktukcinema.extractors
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
|
||||||
import okhttp3.Headers
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
|
|
||||||
class MoshahdaExtractor(private val client: OkHttpClient) {
|
|
||||||
fun videosFromUrl(link: String, headers: Headers): List<Video> {
|
|
||||||
val request = client.newCall(GET(link, headers)).execute().asJsoup()
|
|
||||||
val element = request.selectFirst("script:containsData(sources)")!!
|
|
||||||
val videoList = mutableListOf<Video>()
|
|
||||||
val qualityMap = mapOf("l" to "240p", "n" to "360p", "h" to "480p", "x" to "720p", "o" to "1080p")
|
|
||||||
val data2 = element.data().substringAfter(", file: \"").substringBefore("\"}],")
|
|
||||||
val url = Regex("(.*)_,(.*),\\.urlset/master(.*)").find(data2)
|
|
||||||
val sources = url!!.groupValues[2].split(",")
|
|
||||||
for (quality in sources) {
|
|
||||||
val src = url.groupValues[1] + "_" + quality + "/index-v1-a1" + url.groupValues[3]
|
|
||||||
val video = qualityMap[quality]?.let {
|
|
||||||
Video(src, "Moshahda: $it", src)
|
|
||||||
}
|
|
||||||
if (video != null) {
|
|
||||||
videoList.add(video)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return videoList
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,17 @@
|
|||||||
|
package eu.kanade.tachiyomi.animeextension.ar.tuktukcinema.extractors
|
||||||
|
|
||||||
|
import dev.datlag.jsunpacker.JsUnpacker
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
|
||||||
|
class UpStreamExtractor(private val client: OkHttpClient) {
|
||||||
|
fun videoFromUrl(url: String): List<Video> {
|
||||||
|
val doc = client.newCall(GET(url)).execute().asJsoup()
|
||||||
|
val script = doc.selectFirst("script:containsData(sources)")?.data() ?: return emptyList()
|
||||||
|
val scriptData = if("eval" in script) JsUnpacker.unpackAndCombine(script)!! else script
|
||||||
|
val m3u8 = Regex("sources:\\s*\\[\\{\\s*\\t*file:\\s*[\"']([^\"']+)").find(scriptData)!!.groupValues[1]
|
||||||
|
return Video(m3u8, "Upstream", m3u8).let(::listOf)
|
||||||
|
}
|
||||||
|
}
|
@ -1,57 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.animeextension.ar.tuktukcinema.extractors
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
|
|
||||||
class VidBomExtractor(private val client: OkHttpClient) {
|
|
||||||
fun videosFromUrl(url: String): List<Video> {
|
|
||||||
val doc = client.newCall(GET(url)).execute().asJsoup()
|
|
||||||
val script = doc.selectFirst("script:containsData(sources)")!!
|
|
||||||
val data = script.data().substringAfter("sources: [").substringBefore("],")
|
|
||||||
val sources = data.split("file:\"").drop(1)
|
|
||||||
val videoList = mutableListOf<Video>()
|
|
||||||
for (source in sources) {
|
|
||||||
val src = source.substringBefore("\"")
|
|
||||||
var quality = "Vidbom: " + source.substringAfter("label:\"").substringBefore("\"") // .substringAfter("format: '")
|
|
||||||
if (quality.length > 15) {
|
|
||||||
quality = "Vidshare: 480p"
|
|
||||||
}
|
|
||||||
val video = Video(src, quality, src)
|
|
||||||
videoList.add(video)
|
|
||||||
}
|
|
||||||
return videoList
|
|
||||||
/*Log.i("looool", "$js")
|
|
||||||
val json = JSONObject(js)
|
|
||||||
Log.i("looool", "$json")
|
|
||||||
val videoList = mutableListOf<Video>()
|
|
||||||
val jsonArray = json.getJSONArray("sources")
|
|
||||||
for (i in 0 until jsonArray.length()) {
|
|
||||||
val `object` = jsonArray.getJSONObject(i)
|
|
||||||
val videoUrl = `object`.getString("file")
|
|
||||||
Log.i("looool", videoUrl)
|
|
||||||
val quality = "Vidbom:" + `object`.getString("label")
|
|
||||||
videoList.add(Video(videoUrl, quality, videoUrl))
|
|
||||||
}
|
|
||||||
return videoList*/
|
|
||||||
/*if (jas.contains("sources")) {
|
|
||||||
val js = script.data()
|
|
||||||
val json = JSONObject(js)
|
|
||||||
val videoList = mutableListOf<Video>()
|
|
||||||
val jsonArray = json.getJSONArray("sources")
|
|
||||||
for (i in 0 until jsonArray.length()) {
|
|
||||||
val `object` = jsonArray.getJSONObject(i)
|
|
||||||
val videoUrl = `object`.getString("file")
|
|
||||||
Log.i("lol", videoUrl)
|
|
||||||
val quality = "Vidbom:" + `object`.getString("label")
|
|
||||||
videoList.add(Video(videoUrl, quality, videoUrl))
|
|
||||||
}
|
|
||||||
return videoList
|
|
||||||
} else {
|
|
||||||
val videoList = mutableListOf<Video>()
|
|
||||||
videoList.add(Video(url, "no 2video", null))
|
|
||||||
return videoList
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user