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:
adly98
2022-09-20 11:01:37 +02:00
committed by GitHub
parent 774dc97f0e
commit d6af7c3598
2 changed files with 110 additions and 51 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'موفيزلاند' extName = 'موفيزلاند'
pkgNameSuffix = 'ar.movizland' pkgNameSuffix = 'ar.movizland'
extClass = '.Movizland' extClass = '.Movizland'
extVersionCode = 2 extVersionCode = 3
libVersion = '13' libVersion = '13'
} }

View File

@ -12,13 +12,16 @@ 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.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.FormBody
import okhttp3.Headers import okhttp3.Headers
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import org.jsoup.select.Elements
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.lang.Exception import java.lang.Exception
@ -40,20 +43,30 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
} }
// Popular // Popular
private fun titleEdit(title: String): String { private fun titleEdit(title: String, details: Boolean = false): String {
return if (Regex("فيلم(.*?)م").containsMatchIn(title) and Regex("[A-Za-z]").containsMatchIn(title)) return if (Regex("فيلم (.*?) مترجم").containsMatchIn(title))
Regex("فيلم(.*?)م").find(title)!!.groupValues[1] + "(فيلم)" Regex("فيلم (.*?) مترجم").find(title)!!.groupValues[1] + " (فيلم)" // افلام اجنبيه مترجمه
else if (title.contains("مسلسل")) else if (Regex("فيلم (.*?) مدبلج").containsMatchIn(title))
Regex(if (title.contains("الموسم"))"مسلسل(.*?)الموسم" else "مسلسل(.*?)الحلقة").find(title)!!.groupValues[1] + "سلسل)" Regex("فيلم (.*?) مدبلج").find(title)!!.groupValues[1] + " دبلج)(فيلم)" // افلام اجنبيه مدبلجه
else if (title.contains("انمي")) else if (Regex("فيلم ([^a-zA-Z]+) ([0-9]+)").containsMatchIn(title)) // افلام عربى
Regex(if (title.contains("الموسم"))"انمي(.*?)الموسم" else "انمي(.*?)الحلقة").find(title)!!.groupValues[1] + "(انمى)" 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("برنامج")) else if (title.contains("برنامج"))
Regex(if (title.contains("الموسم"))"برنامج(.*?)الموسم" else "برنامج(.*?)الحلقة").find(title)!!.groupValues[1] + "(برنامج)" Regex(if (title.contains("الموسم"))"برنامج (.*?) الموسم" else "برنامج (.*?) الحلقة").find(title)!!.groupValues[1] + " (برنامج)"
else else
title 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/") override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/page/$page/")
@ -65,26 +78,55 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
return anime 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 // episodes
private fun seasonsNextPageSelector() = "div.BlockItem a" private fun seasonsNextPageSelector() = "div.BlockItem a"
override fun episodeListParse(response: Response): List<SEpisode> { override fun episodeListParse(response: Response): List<SEpisode> {
val episodes = mutableListOf<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) { fun seasonsAdjust(selector: String, seasons: Elements): List<Element> {
// 1 episode in search to whole season var reverse = false
if (!document.select("div.SeriesSingle div.container h2:contains(موفيز لاند) a").isNullOrEmpty()) { for ((i, s) in seasons.withIndex()) {
val seriesLink = document.select("div.SeriesSingle div.container h2:contains(موفيز لاند) a") if (s.select(selector).text().contains("الاول")) {
addEpisodes(client.newCall(GET(seriesLink.attr("href"), headers)).execute().asJsoup()) if (i == 0) reverse = true
return }
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 // Series and movie-series
for (season in document.select(seasonsNextPageSelector())) { for (season in seasonsAdjust("div.BlockTitle", document.select(seasonsNextPageSelector()))) {
season.let { season.let {
val link = it.attr("href") val link = it.attr("href")
// if series > 1 season // if series > 1 season
@ -92,45 +134,54 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
val seasonHTML = client.newCall(GET(link, headers)).execute().asJsoup() val seasonHTML = client.newCall(GET(link, headers)).execute().asJsoup()
for (episode in seasonHTML.select(seasonsNextPageSelector())) { for (episode in seasonHTML.select(seasonsNextPageSelector())) {
episode.run { episode.run {
addEpisode(client.newCall(GET(this.attr("href"), headers)).execute().asJsoup(), "series") addEpisodeNew(this.attr("href"), "series", this.select("div.BlockTitle").text())
} }
} }
} else { } else {
// if series 1 season only // if series 1 season only
addEpisode( val title = it.select("div.BlockTitle").text()
client.newCall(GET(it.attr("href"), headers)).execute().asJsoup(), addEpisodeNew(link, if (title.contains("فيلم")) "assembly" else "series", title)
if (it.select("img").first().attr("alt").contains("فيلم")) "assembly" else "1"
)
} }
} }
} }
} else { } else {
// Movies // 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 episodeListSelector() = "link[rel=canonical]"
override fun episodeFromElement(element: Element): SEpisode = throw Exception("not used") 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 // Video links
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
@ -181,7 +232,7 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
return this 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") override fun videoFromElement(element: Element) = throw Exception("not used")
@ -189,9 +240,12 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override fun searchAnimeFromElement(element: Element): SAnime { override fun searchAnimeFromElement(element: Element): SAnime {
val anime = SAnime.create() 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.setUrlWithoutDomain(element.select("a").attr("href"))
anime.title = titleEdit(element.select("a div.BlockImageItem div.BlockTitle").text()) anime.title = title
return anime 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 searchAnimeSelector(): String = "div.BlocksInner div.BlocksUI div.BlockItem, div.BoxOfficeOtherSide div.BlocksUI div.BlockItem"
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { 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()) { val url = if (query.isNotBlank()) {
"$baseUrl/page/$page/?s=$query" "$baseUrl/page/$page/?s=$newQuery"
} else { } else {
val url = "$baseUrl/page/$page"
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
when (filter) { when (filter) {
is CategoryList -> { is CategoryList -> {
@ -215,7 +271,7 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
} }
} }
} }
return GET(url, headers) throw Exception("اختر قسم")
} }
return GET(url, headers) return GET(url, headers)
} }
@ -226,7 +282,8 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
val anime = SAnime.create() val anime = SAnime.create()
// div.CoverSingle div.CoverSingleContent // div.CoverSingle div.CoverSingleContent
anime.genre = document.select("div.SingleDetails li:contains(النوع) a,div.SingleDetails li:contains(الجودة) a").joinToString(", ") { it.text() } 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.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.description = document.select("div.ServersEmbeds section.story").text().replace(document.select("meta[property=og:title]").attr("content"), "").replace(":", "").trim()
anime.status = SAnime.COMPLETED anime.status = SAnime.COMPLETED
@ -246,6 +303,7 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
// Filters // Filters
override fun getFilterList() = AnimeFilterList( override fun getFilterList() = AnimeFilterList(
AnimeFilter.Header("الفلترات مش هتشتغل لو بتبحث او وهي فاضيه"),
CategoryList(categoriesName), CategoryList(categoriesName),
) )
@ -256,7 +314,8 @@ class Movizland : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
}.toTypedArray() }.toTypedArray()
private fun getCategoryList() = listOf( private fun getCategoryList() = listOf(
CatUnit("افلام", "movies"), CatUnit("اختر", ""),
CatUnit("كل الافلام", "movies"),
CatUnit("افلام اجنبى", "movies/foreign"), CatUnit("افلام اجنبى", "movies/foreign"),
CatUnit("افلام نتفلكس", "movies/netflix"), CatUnit("افلام نتفلكس", "movies/netflix"),
CatUnit("سلاسل افلام", "movies/backs"), CatUnit("سلاسل افلام", "movies/backs"),