Optimize searching and some series not showing episodes (#875)
* Shahid4U extension * optimize search and fix arabic movies name not showing * optimized searching and some series not showing episode
This commit is contained in:
@ -5,7 +5,7 @@ ext {
|
||||
extName = 'موفيزلاند'
|
||||
pkgNameSuffix = 'ar.movizland'
|
||||
extClass = '.Movizland'
|
||||
extVersionCode = 2
|
||||
extVersionCode = 3
|
||||
libVersion = '13'
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,16 @@ 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.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import org.jsoup.select.Elements
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.lang.Exception
|
||||
@ -40,20 +43,30 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
}
|
||||
|
||||
// Popular
|
||||
private fun titleEdit(title: String): String {
|
||||
return if (Regex("فيلم(.*?)م").containsMatchIn(title) and Regex("[A-Za-z]").containsMatchIn(title))
|
||||
Regex("فيلم(.*?)م").find(title)!!.groupValues[1] + "(فيلم)"
|
||||
else if (title.contains("مسلسل"))
|
||||
Regex(if (title.contains("الموسم"))"مسلسل(.*?)الموسم" else "مسلسل(.*?)الحلقة").find(title)!!.groupValues[1] + "(مسلسل)"
|
||||
else if (title.contains("انمي"))
|
||||
Regex(if (title.contains("الموسم"))"انمي(.*?)الموسم" else "انمي(.*?)الحلقة").find(title)!!.groupValues[1] + "(انمى)"
|
||||
private fun titleEdit(title: String, details: Boolean = false): String {
|
||||
return if (Regex("فيلم (.*?) مترجم").containsMatchIn(title))
|
||||
Regex("فيلم (.*?) مترجم").find(title)!!.groupValues[1] + " (فيلم)" // افلام اجنبيه مترجمه
|
||||
else if (Regex("فيلم (.*?) مدبلج").containsMatchIn(title))
|
||||
Regex("فيلم (.*?) مدبلج").find(title)!!.groupValues[1] + " (مدبلج)(فيلم)" // افلام اجنبيه مدبلجه
|
||||
else if (Regex("فيلم ([^a-zA-Z]+) ([0-9]+)").containsMatchIn(title)) // افلام عربى
|
||||
Regex("فيلم ([^a-zA-Z]+) ([0-9]+)").find(title)!!.groupValues[1] + " (فيلم)"
|
||||
else if (title.contains("مسلسل")) {
|
||||
if (title.contains("الموسم") and details) {
|
||||
val newTitle = Regex("مسلسل (.*?) الموسم (.*?) الحلقة ([0-9]+)").find(title)
|
||||
"${newTitle!!.groupValues[1]} (م.${newTitle.groupValues[2]})(${newTitle.groupValues[3]}ح)"
|
||||
} else if (title.contains("الحلقة")and details) {
|
||||
val newTitle = Regex("مسلسل (.*?) الحلقة ([0-9]+)").find(title)
|
||||
"${newTitle!!.groupValues[1]} (${newTitle.groupValues[2]}ح)"
|
||||
} else Regex(if (title.contains("الموسم")) "مسلسل (.*?) الموسم" else "مسلسل (.*?) الحلقة").find(title)!!.groupValues[1] + " (مسلسل)"
|
||||
} else if (title.contains("انمي"))
|
||||
return Regex(if (title.contains("الموسم"))"انمي (.*?) الموسم" else "انمي (.*?) الحلقة").find(title)!!.groupValues[1] + " (انمى)"
|
||||
else if (title.contains("برنامج"))
|
||||
Regex(if (title.contains("الموسم"))"برنامج(.*?)الموسم" else "برنامج(.*?)الحلقة").find(title)!!.groupValues[1] + "(برنامج)"
|
||||
Regex(if (title.contains("الموسم"))"برنامج (.*?) الموسم" else "برنامج (.*?) الحلقة").find(title)!!.groupValues[1] + " (برنامج)"
|
||||
else
|
||||
title
|
||||
}
|
||||
|
||||
override fun popularAnimeSelector(): String = "div.BoxOfficeOtherSide div.BlocksUI div.BlockItem"
|
||||
override fun popularAnimeSelector(): String = "div.BlocksInner div.BlocksUI div.BlockItem, div.BoxOfficeOtherSide div.BlocksUI div.BlockItem"
|
||||
|
||||
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/page/$page/")
|
||||
|
||||
@ -65,26 +78,55 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
return anime
|
||||
}
|
||||
|
||||
override fun popularAnimeNextPageSelector(): String = "div.pagination div.navigation ul li.active + li a"
|
||||
override fun popularAnimeNextPageSelector(): String = "div.pagination li a.next"
|
||||
|
||||
// episodes
|
||||
private fun seasonsNextPageSelector() = "div.BlockItem a"
|
||||
|
||||
override fun episodeListParse(response: Response): List<SEpisode> {
|
||||
val episodes = mutableListOf<SEpisode>()
|
||||
fun addEpisode(document: Document, season: String) {
|
||||
document.select(episodeListSelector()).map { episodes.add(episodeFromElement(it, season)) }
|
||||
|
||||
fun addEpisodeNew(url: String, type: String, title: String = "") {
|
||||
val episode = SEpisode.create()
|
||||
episode.setUrlWithoutDomain(url)
|
||||
if (type == "assembly")
|
||||
episode.name = title.replace("فيلم", "").trim()
|
||||
else if (type == "movie")
|
||||
episode.name = "watch"
|
||||
else if (Regex("الموسم (.*)").containsMatchIn(title))
|
||||
episode.name = Regex("الموسم (.*)").find(title)!!.value.replace("مترجمة", "").replace("والاخيرة", "").trim()
|
||||
else if (Regex("الحلقة (.*)").containsMatchIn(title))
|
||||
episode.name = Regex("الحلقة (.*)").find(title)!!.value.replace("مترجمة", "").replace("والاخيرة", "").trim()
|
||||
else if (Regex("حلقة (.*)").containsMatchIn(title))
|
||||
episode.name = Regex("حلقة (.*)").find(title)!!.value.replace("مترجمة", "").replace("والاخيرة", "").trim()
|
||||
else
|
||||
episode.name = title
|
||||
|
||||
episodes.add(episode)
|
||||
}
|
||||
fun addEpisodes(document: Document) {
|
||||
// 1 episode in search to whole season
|
||||
if (!document.select("div.SeriesSingle div.container h2:contains(موفيز لاند) a").isNullOrEmpty()) {
|
||||
val seriesLink = document.select("div.SeriesSingle div.container h2:contains(موفيز لاند) a")
|
||||
addEpisodes(client.newCall(GET(seriesLink.attr("href"), headers)).execute().asJsoup())
|
||||
return
|
||||
fun seasonsAdjust(selector: String, seasons: Elements): List<Element> {
|
||||
var reverse = false
|
||||
for ((i, s) in seasons.withIndex()) {
|
||||
if (s.select(selector).text().contains("الاول")) {
|
||||
if (i == 0) reverse = true
|
||||
}
|
||||
if (s.select(selector).text().contains("الثان")) {
|
||||
if (i != 0) {
|
||||
seasons.remove(s)
|
||||
seasons.add(1, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (document.select("link[rel=canonical]").attr("href").contains("series")) {
|
||||
return if (reverse) seasons.reversed() else seasons
|
||||
}
|
||||
fun addEpisodes(response: Response) {
|
||||
val document = response.asJsoup()
|
||||
val url = response.request.url.toString()
|
||||
// 1 episode in search to whole season
|
||||
|
||||
if (url.contains("series")) {
|
||||
// Series and movie-series
|
||||
for (season in document.select(seasonsNextPageSelector())) {
|
||||
for (season in seasonsAdjust("div.BlockTitle", document.select(seasonsNextPageSelector()))) {
|
||||
season.let {
|
||||
val link = it.attr("href")
|
||||
// if series > 1 season
|
||||
@ -92,45 +134,54 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
val seasonHTML = client.newCall(GET(link, headers)).execute().asJsoup()
|
||||
for (episode in seasonHTML.select(seasonsNextPageSelector())) {
|
||||
episode.run {
|
||||
addEpisode(client.newCall(GET(this.attr("href"), headers)).execute().asJsoup(), "series")
|
||||
addEpisodeNew(this.attr("href"), "series", this.select("div.BlockTitle").text())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if series 1 season only
|
||||
addEpisode(
|
||||
client.newCall(GET(it.attr("href"), headers)).execute().asJsoup(),
|
||||
if (it.select("img").first().attr("alt").contains("فيلم")) "assembly" else "1"
|
||||
)
|
||||
val title = it.select("div.BlockTitle").text()
|
||||
addEpisodeNew(link, if (title.contains("فيلم")) "assembly" else "series", title)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Movies
|
||||
addEpisode(document, "0")
|
||||
var countSeasons = 0
|
||||
var count = 0
|
||||
for (season in seasonsAdjust("a", document.select("div.SeriesSingle ul.DropdownFilter li"))) {
|
||||
countSeasons++
|
||||
val seasonData = season.select("a").attr("data-term")
|
||||
val refererHeaders = Headers.headersOf("referer", url, "x-requested-with", "XMLHttpRequest")
|
||||
val requestBody = FormBody.Builder().add("season", seasonData).build()
|
||||
val getEpisodes = client.newCall(POST("${baseUrl}wp-content/themes/Moviezland2022/EpisodesList.php", refererHeaders, requestBody)).execute().asJsoup()
|
||||
for (episode in getEpisodes.select("div.EpisodeItem").reversed()) {
|
||||
addEpisodeNew(episode.select("a").attr("href"), "series", season.select("a").text() + " " + episode.select("a").text())
|
||||
}
|
||||
}
|
||||
if (countSeasons == 0) {
|
||||
for (episode in document.select("div.EpisodeItem").reversed()) {
|
||||
count++
|
||||
addEpisodeNew(
|
||||
episode.select("a").attr("href"),
|
||||
"series",
|
||||
document.select("div.SeriesSingle h2 span a").text() + " " + episode.select("a").text()
|
||||
)
|
||||
}
|
||||
if (count == 0)
|
||||
addEpisodeNew(url, "movie")
|
||||
}
|
||||
}
|
||||
}
|
||||
addEpisodes(response.asJsoup())
|
||||
return episodes.reversed()
|
||||
|
||||
addEpisodes(response)
|
||||
|
||||
return episodes
|
||||
}
|
||||
|
||||
override fun episodeListSelector() = "link[rel=canonical]"
|
||||
|
||||
override fun episodeFromElement(element: Element): SEpisode = throw Exception("not used")
|
||||
|
||||
private fun episodeFromElement(element: Element, season: String): SEpisode {
|
||||
// movie
|
||||
val episode = SEpisode.create()
|
||||
episode.setUrlWithoutDomain(element.attr("href"))
|
||||
episode.name = element.ownerDocument().select("meta[property=og:title]").attr("content")
|
||||
if (season == "assembly")
|
||||
episode.name = titleEdit(episode.name)
|
||||
else if (episode.name.contains("فيلم"))
|
||||
episode.name = "watch"
|
||||
else
|
||||
episode.name = Regex("الموسم(.*?)مترجمة").find(episode.name)!!.value.replace("مترجمة", "").replace("والاخيرة", "").trim()
|
||||
return episode
|
||||
}
|
||||
|
||||
// Video links
|
||||
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
@ -181,7 +232,7 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun videoUrlParse(document: Document) = throw Exception("not used")
|
||||
override fun videoUrlParse(document: Document) = throw Exception("Stub")
|
||||
|
||||
override fun videoFromElement(element: Element) = throw Exception("not used")
|
||||
|
||||
@ -189,9 +240,12 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
|
||||
override fun searchAnimeFromElement(element: Element): SAnime {
|
||||
val anime = SAnime.create()
|
||||
anime.thumbnail_url = element.select("a div.BlockImageItem img").attr("data-src")
|
||||
val title = titleEdit(element.select("a div.BlockImageItem div.BlockTitle").text(), true)
|
||||
anime.thumbnail_url = element.select("a div.BlockImageItem img").attr("src")
|
||||
if (anime.thumbnail_url.isNullOrEmpty()) anime.thumbnail_url =
|
||||
element.select("a div.BlockImageItem img").attr("data-src")
|
||||
anime.setUrlWithoutDomain(element.select("a").attr("href"))
|
||||
anime.title = titleEdit(element.select("a div.BlockImageItem div.BlockTitle").text())
|
||||
anime.title = title
|
||||
return anime
|
||||
}
|
||||
|
||||
@ -200,10 +254,12 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
override fun searchAnimeSelector(): String = "div.BlocksInner div.BlocksUI div.BlockItem, div.BoxOfficeOtherSide div.BlocksUI div.BlockItem"
|
||||
|
||||
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
|
||||
var newQuery = query
|
||||
if(Regex("(.*)\\(").containsMatchIn(query))
|
||||
newQuery = Regex("(.*)\\(").find(query)!!.groupValues[1].replace("(","")
|
||||
val url = if (query.isNotBlank()) {
|
||||
"$baseUrl/page/$page/?s=$query"
|
||||
"$baseUrl/page/$page/?s=$newQuery"
|
||||
} else {
|
||||
val url = "$baseUrl/page/$page"
|
||||
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
||||
when (filter) {
|
||||
is CategoryList -> {
|
||||
@ -215,7 +271,7 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
}
|
||||
}
|
||||
}
|
||||
return GET(url, headers)
|
||||
throw Exception("اختر قسم")
|
||||
}
|
||||
return GET(url, headers)
|
||||
}
|
||||
@ -226,7 +282,8 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
val anime = SAnime.create()
|
||||
// div.CoverSingle div.CoverSingleContent
|
||||
anime.genre = document.select("div.SingleDetails li:contains(النوع) a,div.SingleDetails li:contains(الجودة) a").joinToString(", ") { it.text() }
|
||||
anime.title = titleEdit(document.select("meta[property=og:title]").attr("content"))
|
||||
anime.title = if (document.select("h2.postTitle").isNullOrEmpty())
|
||||
titleEdit(document.select("div.H1Title h1").text()) else titleEdit(document.select("h2.postTitle").text())
|
||||
anime.author = document.select("div.SingleDetails li:contains(دولة) a").text()
|
||||
anime.description = document.select("div.ServersEmbeds section.story").text().replace(document.select("meta[property=og:title]").attr("content"), "").replace(":", "").trim()
|
||||
anime.status = SAnime.COMPLETED
|
||||
@ -246,6 +303,7 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
// Filters
|
||||
|
||||
override fun getFilterList() = AnimeFilterList(
|
||||
AnimeFilter.Header("الفلترات مش هتشتغل لو بتبحث او وهي فاضيه"),
|
||||
CategoryList(categoriesName),
|
||||
)
|
||||
|
||||
@ -256,7 +314,8 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
}.toTypedArray()
|
||||
|
||||
private fun getCategoryList() = listOf(
|
||||
CatUnit("افلام", "movies"),
|
||||
CatUnit("اختر", ""),
|
||||
CatUnit("كل الافلام", "movies"),
|
||||
CatUnit("افلام اجنبى", "movies/foreign"),
|
||||
CatUnit("افلام نتفلكس", "movies/netflix"),
|
||||
CatUnit("سلاسل افلام", "movies/backs"),
|
||||
|
Reference in New Issue
Block a user