|
|
|
@ -12,9 +12,8 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
|
|
|
|
|
import eu.kanade.tachiyomi.animesource.model.Video
|
|
|
|
|
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
|
|
|
|
import eu.kanade.tachiyomi.network.GET
|
|
|
|
|
import eu.kanade.tachiyomi.network.POST
|
|
|
|
|
import eu.kanade.tachiyomi.util.asJsoup
|
|
|
|
|
import okhttp3.FormBody
|
|
|
|
|
import okhttp3.Headers
|
|
|
|
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
|
|
|
import okhttp3.OkHttpClient
|
|
|
|
|
import okhttp3.Request
|
|
|
|
@ -29,7 +28,7 @@ class ArabSeed : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|
|
|
|
|
|
|
|
|
override val name = "عرب سيد"
|
|
|
|
|
|
|
|
|
|
override val baseUrl = "https://m.arabseed.sbs"
|
|
|
|
|
override val baseUrl = "https://a.arabseed.ink"
|
|
|
|
|
|
|
|
|
|
override val lang = "ar"
|
|
|
|
|
|
|
|
|
@ -57,20 +56,53 @@ class ArabSeed : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|
|
|
|
override fun popularAnimeNextPageSelector(): String = "ul.page-numbers li a.next"
|
|
|
|
|
|
|
|
|
|
// Episodes
|
|
|
|
|
override fun episodeListSelector() = "div.WatchButtons > a[href~=watch]"
|
|
|
|
|
override fun episodeListSelector() = "div.ContainerEpisodesList a"
|
|
|
|
|
|
|
|
|
|
override fun episodeListParse(response: Response): List<SEpisode> {
|
|
|
|
|
val episodes = mutableListOf<SEpisode>()
|
|
|
|
|
fun addEpisodes(document: Document) {
|
|
|
|
|
if (document.select(episodeListSelector()).isNullOrEmpty()) {
|
|
|
|
|
// add movie
|
|
|
|
|
document.select("link[rel=canonical]").map { episodes.add(episodeFromElement(it)) }
|
|
|
|
|
} else {
|
|
|
|
|
document.select(episodeListSelector()).map { episodes.add(episodesFromElement(it)) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
addEpisodes(response.asJsoup())
|
|
|
|
|
return episodes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun episodeFromElement(element: Element): SEpisode {
|
|
|
|
|
val episode = SEpisode.create()
|
|
|
|
|
episode.setUrlWithoutDomain(element.attr("href"))
|
|
|
|
|
episode.name = element.ownerDocument().select("div.InfoPartOne a h1.Title").text().replace(" مترجم", "").replace("فيلم ", "")
|
|
|
|
|
episode.name = "مشاهدة"
|
|
|
|
|
return episode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun episodesFromElement(element: Element): SEpisode {
|
|
|
|
|
val episode = SEpisode.create()
|
|
|
|
|
val epNum = getNumberFromEpsString(element.text())
|
|
|
|
|
episode.setUrlWithoutDomain(element.attr("href"))
|
|
|
|
|
episode.name = element.text()
|
|
|
|
|
episode.episode_number = when {
|
|
|
|
|
(epNum.isNotEmpty()) -> epNum.toFloat()
|
|
|
|
|
else -> 1F
|
|
|
|
|
}
|
|
|
|
|
return episode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun getNumberFromEpsString(epsStr: String): String {
|
|
|
|
|
return epsStr.filter { it.isDigit() }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Video urls
|
|
|
|
|
|
|
|
|
|
override fun videoListParse(response: Response): List<Video> {
|
|
|
|
|
val document = response.asJsoup()
|
|
|
|
|
return videosFromElement(document)
|
|
|
|
|
val watchUrl = document.select("a.watchBTn").attr("href")
|
|
|
|
|
val refererHeaders = Headers.headersOf("referer", "https://a.arabseed.ink/")
|
|
|
|
|
val document1 = client.newCall(GET(watchUrl, refererHeaders)).execute().asJsoup()
|
|
|
|
|
return videosFromElement(document1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun videoListSelector() = "div.containerServers ul li" // ul#playeroptionsul
|
|
|
|
@ -79,25 +111,10 @@ class ArabSeed : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|
|
|
|
val videoList = mutableListOf<Video>()
|
|
|
|
|
val elements = document.select(videoListSelector())
|
|
|
|
|
for (element in elements) {
|
|
|
|
|
val location = element.ownerDocument().location()
|
|
|
|
|
val videoHeaders = headers.newBuilder()
|
|
|
|
|
.set("Referer", "https://m.arabseed.sbs/")
|
|
|
|
|
.set("X-Requested-With", "XMLHttpRequest")
|
|
|
|
|
.build()
|
|
|
|
|
// Headers.headersOf("Referer", location)
|
|
|
|
|
val dataPost = element.attr("data-post")
|
|
|
|
|
val dataServer = element.attr("data-server")
|
|
|
|
|
val dataQu = element.attr("data-qu")
|
|
|
|
|
val pageData = FormBody.Builder()
|
|
|
|
|
.add("post_id", dataPost)
|
|
|
|
|
.add("server", dataServer)
|
|
|
|
|
.add("qu", dataQu)
|
|
|
|
|
.build()
|
|
|
|
|
val ajax1 = "https://m.arabseed.sbs/wp-content/themes/Elshaikh2021/Ajaxat/Single/Server.php"
|
|
|
|
|
val ajax = client.newCall(POST(ajax1, videoHeaders, pageData)).execute().asJsoup()
|
|
|
|
|
val embedUrl = ajax.select("iframe").attr("src")
|
|
|
|
|
val dataQu = element.text()
|
|
|
|
|
val embedUrl = element.attr("data-link")
|
|
|
|
|
when {
|
|
|
|
|
embedUrl.contains("seeeed") -> {
|
|
|
|
|
embedUrl.contains("reviewtech") -> {
|
|
|
|
|
val iframeResponse = client.newCall(GET(embedUrl)).execute().asJsoup()
|
|
|
|
|
val videoUrl = iframeResponse.select("source").attr("src")
|
|
|
|
|
val video = Video(embedUrl, dataQu + "p", videoUrl.replace("https", "http"))
|
|
|
|
@ -136,7 +153,7 @@ class ArabSeed : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|
|
|
|
val anime = SAnime.create()
|
|
|
|
|
anime.setUrlWithoutDomain(element.attr("href"))
|
|
|
|
|
anime.title = element.select("div.BlockName h4").text()
|
|
|
|
|
anime.thumbnail_url = element.select("img").first().attr("src")
|
|
|
|
|
anime.thumbnail_url = element.select("img").first().attr("data-src")
|
|
|
|
|
return anime
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -169,7 +186,7 @@ class ArabSeed : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|
|
|
|
override fun animeDetailsParse(document: Document): SAnime {
|
|
|
|
|
val anime = SAnime.create()
|
|
|
|
|
anime.thumbnail_url = document.select("div.Poster img").first().attr("data-src")
|
|
|
|
|
anime.title = document.select("div.InfoPartOne a h1.Title").text().replace(" مترجم", "").replace("فيلم ", "")
|
|
|
|
|
anime.title = document.select("div.BreadCrumbs ol li:last-child a span").text().replace(" مترجم", "").replace("فيلم ", "")
|
|
|
|
|
anime.genre = document.select("div.MetaTermsInfo > li:contains(النوع) > a").joinToString(", ") { it.text() }
|
|
|
|
|
anime.description = document.select("div.StoryLine p").text()
|
|
|
|
|
anime.status = SAnime.COMPLETED
|
|
|
|
@ -199,7 +216,16 @@ class ArabSeed : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|
|
|
|
Type("افلام انيميشن", "%d8%a7%d9%81%d9%84%d8%a7%d9%85-%d8%a7%d9%86%d9%8a%d9%85%d9%8a%d8%b4%d9%86/"),
|
|
|
|
|
Type("افلام كلاسيكيه", "%d8%a7%d9%81%d9%84%d8%a7%d9%85-%d9%83%d9%84%d8%a7%d8%b3%d9%8a%d9%83%d9%8a%d9%87/"),
|
|
|
|
|
Type("افلام مدبلجة", "%d8%a7%d9%81%d9%84%d8%a7%d9%85-%d9%85%d8%af%d8%a8%d9%84%d8%ac%d8%a9/"),
|
|
|
|
|
Type("افلام Netfilx", "netfilx/افلام-netfilx/")
|
|
|
|
|
Type("افلام Netfilx", "netfilx/افلام-netfilx/"),
|
|
|
|
|
Type("مسلسلات عربي", "%d9%85%d8%b3%d9%84%d8%b3%d9%84%d8%a7%d8%aa-%d8%b9%d8%b1%d8%a8%d9%8a/"),
|
|
|
|
|
Type("مسلسلات اجنبي", "foreign-series/"),
|
|
|
|
|
Type("مسلسلات تركيه", "turkish-series-1/"),
|
|
|
|
|
Type("برامج تلفزيونية", "%d8%a8%d8%b1%d8%a7%d9%85%d8%ac-%d8%aa%d9%84%d9%81%d8%b2%d9%8a%d9%88%d9%86%d9%8a%d8%a9/"),
|
|
|
|
|
Type("مسلسلات كرتون", "%d9%85%d8%b3%d9%84%d8%b3%d9%84%d8%a7%d8%aa-%d9%83%d8%b1%d8%aa%d9%88%d9%86/"),
|
|
|
|
|
Type("مسلسلات رمضان 2019", "%d9%85%d8%b3%d9%84%d8%b3%d9%84%d8%a7%d8%aa-%d8%b1%d9%85%d8%b6%d8%a7%d9%86-2019/"),
|
|
|
|
|
Type("مسلسلات رمضان 2020", "%d9%85%d8%b3%d9%84%d8%b3%d9%84%d8%a7%d8%aa-%d8%b1%d9%85%d8%b6%d8%a7%d9%86-2020-hd/"),
|
|
|
|
|
Type("مسلسلات رمضان 2021", "%d9%85%d8%b3%d9%84%d8%b3%d9%84%d8%a7%d8%aa-%d8%b1%d9%85%d8%b6%d8%a7%d9%86-2021/"),
|
|
|
|
|
Type("مسلسلات Netfilx", "netfilx/%d9%85%d8%b3%d9%84%d8%b3%d9%84%d8%a7%d8%aa-netfilz/")
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@ -221,7 +247,7 @@ class ArabSeed : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|
|
|
|
title = "Preferred Quality"
|
|
|
|
|
entries = arrayOf("1080p", "720p", "480p", "360p")
|
|
|
|
|
entryValues = arrayOf("1080", "720", "480", "360")
|
|
|
|
|
setDefaultValue("سيرفر عرب سيد - 720p")
|
|
|
|
|
setDefaultValue("720")
|
|
|
|
|
summary = "%s"
|
|
|
|
|
|
|
|
|
|
setOnPreferenceChangeListener { _, newValue ->
|
|
|
|
|