[Feature] Add Recommendations and Tags to various providers. (#583)

* PinoyMoviePedia: Add recommendations and tags.

* PinoyMoviesEs: Add recs and tags.

* pinoyHD: Add tags. Fetch hidden links in movie description.

* DramaSee: Add tags and recs.

* WatchAsian: Load tags from details page of url.

* Kdramahood: Add recs.

* [skip ci] Replace isNotEmpty() with isNotBlank()

* Minor refactor to PinoyHD and PinoyMoviesEs HomePage entries.
This commit is contained in:
Jace 2022-02-06 19:43:12 +08:00 committed by GitHub
parent 11e10a9bd8
commit 765aa7c5af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 350 additions and 190 deletions

View File

@ -15,7 +15,7 @@ class UpstreamExtractor: ExtractorApi() {
//Log.i(this.name, "Result => (no extractor) ${url}")
val sources: MutableList<ExtractorLink> = mutableListOf()
val doc = app.get(url, referer = referer).text
if (doc.isNotEmpty()) {
if (doc.isNotBlank()) {
var reg = Regex("(?<=master)(.*)(?=hls)")
val result = reg.find(doc)?.groupValues?.map {
it.trim('|')

View File

@ -21,7 +21,7 @@ open class VoeExtractor : ExtractorApi() {
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
val doc = app.get(url).text
if (doc.isNotEmpty()) {
if (doc.isNotBlank()) {
val start = "const sources ="
var src = doc.substring(doc.indexOf(start))
src = src.substring(start.length, src.indexOf(";"))

View File

@ -16,7 +16,7 @@ class AsianEmbedHelper {
links.apmap {
val datavid = it.attr("data-video") ?: ""
//Log.i("AsianEmbed", "Result => (datavid) ${datavid}")
if (datavid.isNotEmpty()) {
if (datavid.isNotBlank()) {
val res = loadExtractor(datavid, url, callback)
Log.i("AsianEmbed", "Result => ($res) (datavid) $datavid")
}

View File

@ -37,7 +37,7 @@ class VstreamhubHelper {
val startString = "window.open(["
val bb = aa.substring(aa.indexOf(startString))
val datavid = bb.substring(startString.length, bb.indexOf("]")).removeSurrounding("\"")
if (datavid.isNotEmpty()) {
if (datavid.isNotBlank()) {
loadExtractor(datavid, url, callback)
//Log.i(baseName, "Result => (datavid) ${datavid}")
}

View File

@ -91,8 +91,24 @@ class DramaSeeProvider : MainAPI() {
val year = if (title.length > 5) { title.substring(title.length - 5)
.trim().trimEnd(')').toIntOrNull() } else { null }
//Log.i(this.name, "Result => (year) ${title.substring(title.length - 5)}")
val descript = body?.select("div.series-body")?.firstOrNull()
?.select("div.js-content")?.text()
val seriesBody = body?.select("div.series-body")
val descript = seriesBody?.firstOrNull()?.select("div.js-content")?.text()
val tags = seriesBody?.select("div.series-tags > a")?.mapNotNull { it?.text()?.trim() ?: return@mapNotNull null }
val recs = body?.select("ul.series > li")?.mapNotNull {
val a = it.select("a.series-img") ?: return@mapNotNull null
val aUrl = fixUrlNull(a.attr("href")) ?: return@mapNotNull null
val aImg = fixUrlNull(a.select("img")?.attr("src"))
val aName = a.select("img")?.attr("alt") ?: return@mapNotNull null
val aYear = aName.trim().takeLast(5).removeSuffix(")").toIntOrNull()
MovieSearchResponse(
url = aUrl,
name = aName,
type = TvType.Movie,
posterUrl = aImg,
year = aYear,
apiName = this.name
)
}
// Episodes Links
val episodeList = ArrayList<TvSeriesEpisode>()
@ -101,7 +117,7 @@ class DramaSeeProvider : MainAPI() {
val count = innerA.select("span.episode")?.text()?.toIntOrNull() ?: 0
val epLink = fixUrlNull(innerA.attr("href")) ?: return@forEach
//Log.i(this.name, "Result => (epLink) ${epLink}")
if (epLink.isNotEmpty()) {
if (epLink.isNotBlank()) {
// Fetch video links
val epVidLinkEl = app.get(epLink, referer = mainUrl).document
val ajaxUrl = epVidLinkEl.select("div#js-player")?.attr("embed")
@ -111,7 +127,7 @@ class DramaSeeProvider : MainAPI() {
val listOfLinks = mutableListOf<String>()
innerPage.select("div.player.active > main > div")?.forEach { em ->
val href = fixUrlNull(em.attr("src")) ?: ""
if (href.isNotEmpty()) {
if (href.isNotBlank()) {
listOfLinks.add(href)
}
}
@ -133,20 +149,30 @@ class DramaSeeProvider : MainAPI() {
//If there's only 1 episode, consider it a movie.
if (episodeList.size == 1) {
return MovieLoadResponse(title, url, this.name, TvType.Movie, episodeList[0].data, poster, year, descript, null, null)
return MovieLoadResponse(
name = title,
url = url,
apiName = this.name,
type = TvType.Movie,
dataUrl = episodeList[0].data,
posterUrl = poster,
year = year,
plot = descript,
recommendations = recs,
tags = tags
)
}
return TvSeriesLoadResponse(
title,
url,
this.name,
TvType.TvSeries,
episodeList.reversed(),
poster,
year,
descript,
null,
null,
null
name = title,
url = url,
apiName = this.name,
type = TvType.TvSeries,
episodes = episodeList.reversed(),
posterUrl = poster,
year = year,
plot = descript,
recommendations = recs,
tags = tags
)
}

View File

@ -110,6 +110,24 @@ class KdramaHoodProvider : MainAPI() {
res
} catch (e: Exception) { null }
val recs = doc.select("div.sidebartv > div.tvitemrel")?.mapNotNull {
val a = it?.select("a") ?: return@mapNotNull null
val aUrl = fixUrlNull(a.attr("href")) ?: return@mapNotNull null
val aImg = a.select("img")
val aCover = fixUrlNull(aImg?.attr("src")) ?: fixUrlNull(aImg?.attr("data-src"))
val aNameYear = a.select("div.datatvrel") ?: return@mapNotNull null
val aName = aNameYear.select("h4")?.text() ?: aImg?.attr("alt") ?: return@mapNotNull null
val aYear = aName.trim().takeLast(5).removeSuffix(")").toIntOrNull()
MovieSearchResponse(
url = aUrl,
name = aName,
type = TvType.Movie,
posterUrl = aCover,
year = aYear,
apiName = this.name
)
}
// Episodes Links
val episodeList = inner?.select("ul.episodios > li")?.mapNotNull { ep ->
//Log.i(this.name, "Result => (ep) ${ep}")
@ -119,7 +137,7 @@ class KdramaHoodProvider : MainAPI() {
//Log.i(this.name, "Result => (innerA) ${innerA}")
val epLink = fixUrlNull(innerA.attr("href")) ?: return@mapNotNull null
//Log.i(this.name, "Result => (epLink) ${epLink}")
if (epLink.isNotEmpty()) {
if (epLink.isNotBlank()) {
// Fetch video links
val epVidLinkEl = app.get(epLink, referer = mainUrl).document
val epLinksContent = epVidLinkEl.selectFirst("div.player_nav > script")?.html()
@ -131,20 +149,10 @@ class KdramaHoodProvider : MainAPI() {
Jsoup.parse(epLinksContent)?.select("div")?.forEach { em ->
val href = em?.html()?.trim()?.removePrefix("'") ?: return@forEach
//Log.i(this.name, "Result => (ep#$count link) $href")
if (href.isNotEmpty()) {
if (href.isNotBlank()) {
listOfLinks.add(fixUrl(href))
}
}
/* Doesn't get all links for some reasons
val rex = Regex("(?<=ifr_target.src =)(.*)(?=';)")
rex.find(epLinksContent)?.groupValues?.forEach { em ->
val href = em.trim()
Log.i(this.name, "Result => (ep #$count href) $href")
if (href.isNotEmpty()) {
listOfLinks.add(href)
}
}
*/
}
}
TvSeriesEpisode(
@ -159,20 +167,28 @@ class KdramaHoodProvider : MainAPI() {
//If there's only 1 episode, consider it a movie.
if (episodeList.size == 1) {
return MovieLoadResponse(title, url, this.name, TvType.Movie, episodeList[0].data, poster, year, descript, null, null)
return MovieLoadResponse(
name = title,
url = url,
apiName = this.name,
type = TvType.Movie,
dataUrl = episodeList[0].data,
posterUrl = poster,
year = year,
plot = descript,
recommendations = recs
)
}
return TvSeriesLoadResponse(
title,
url,
this.name,
TvType.TvSeries,
episodeList.reversed(),
poster,
year,
descript,
null,
null,
null
name = title,
url = url,
apiName = this.name,
type = TvType.TvSeries,
episodes = episodeList.reversed(),
posterUrl = poster,
year = year,
plot = descript,
recommendations = recs
)
}
@ -184,7 +200,7 @@ class KdramaHoodProvider : MainAPI() {
): Boolean {
var count = 0
mapper.readValue<List<String>>(data).apmap { item ->
if (item.isNotEmpty()) {
if (item.isNotBlank()) {
count++
var url = item.trim()
if (url.startsWith("//")) {

View File

@ -1,5 +1,6 @@
package com.lagradost.cloudstream3.movieproviders
import android.util.Log
import com.fasterxml.jackson.module.kotlin.readValue
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.AppUtils.toJson
@ -23,38 +24,31 @@ class PinoyHDXyzProvider : MainAPI() {
mainbody?.select("div.section-cotent.col-md-12.bordert")?.forEach { row ->
val title = row?.select("div.title-section.tt")?.text() ?: "<Row>"
val inner = row?.select("li.img_frame.preview-tumb7")
if (inner != null) {
val elements: List<SearchResponse> = inner.map {
// Get inner div from article
val innerBody = it?.select("a")?.firstOrNull()
// Fetch details
val name = it?.text() ?: ""
val link = innerBody?.attr("href") ?: ""
val imgsrc = innerBody?.select("img")?.attr("src")
val image = when (!imgsrc.isNullOrEmpty()) {
true -> "${mainUrl}${imgsrc}"
false -> null
}
//Log.i(this.name, "Result => (innerBody, image) ${innerBody} / ${image}")
// Get Year from Link
val rex = Regex("_(\\d+)_")
val yearRes = rex.find(link)?.value ?: ""
val year = yearRes.replace("_", "").toIntOrNull()
//Log.i(this.name, "Result => (yearRes, year) ${yearRes} / ${year}")
MovieSearchResponse(
name,
link,
this.name,
TvType.Movie,
image,
year,
null,
)
}.filter { a -> a.url.isNotEmpty() }
.filter { b -> b.name.isNotEmpty() }
.distinctBy { c -> c.url }
// Add
val elements = row?.select("li.img_frame.preview-tumb7")?.mapNotNull {
// Get inner div from article
val innerBody = it?.selectFirst("a") ?: return@mapNotNull null
// Fetch details
val name = it.text()
if (name.isNullOrBlank()) { return@mapNotNull null }
val link = innerBody.attr("href") ?: return@mapNotNull null
val image = fixUrlNull(innerBody.select("img")?.attr("src"))
//Log.i(this.name, "Result => (innerBody, image) ${innerBody} / ${image}")
// Get Year from Link
val rex = Regex("_(\\d+)_")
val year = rex.find(link)?.value?.replace("_", "")?.toIntOrNull()
//Log.i(this.name, "Result => (yearRes, year) ${yearRes} / ${year}")
MovieSearchResponse(
name = name,
url = link,
apiName = this.name,
type = TvType.Movie,
posterUrl = image,
year = year
)
}?.distinctBy { c -> c.url } ?: listOf()
// Add to Homepage
if (elements.isNotEmpty()) {
all.add(
HomePageList(
title, elements
@ -78,12 +72,12 @@ class PinoyHDXyzProvider : MainAPI() {
val image = null // site provides no image on search page
MovieSearchResponse(
title,
link,
this.name,
TvType.Movie,
image,
year
name = title,
url = link,
apiName = this.name,
type = TvType.Movie,
posterUrl = image,
year = year
)
}?.distinctBy { c -> c.url } ?: listOf()
}
@ -93,29 +87,57 @@ class PinoyHDXyzProvider : MainAPI() {
val body = doc.getElementsByTag("body")
val inner = body?.select("div.info")
// Video links
val listOfLinks: MutableList<String> = mutableListOf()
// Video details
val imgLinkCode = inner?.select("div.portfolio-tumb.ph-link > img")?.attr("src")
val poster = if (!imgLinkCode.isNullOrEmpty()) { "${mainUrl}${imgLinkCode}" } else { null }
var title = ""
var year: Int? = null
var tags: List<String>? = null
val poster = fixUrlNull(inner?.select("div.portfolio-tumb.ph-link > img")?.attr("src"))
//Log.i(this.name, "Result => (imgLinkCode) ${imgLinkCode}")
val title = inner?.select("td.trFon2.entt")?.firstOrNull()?.text() ?: "<Untitled>"
var yearRes = inner?.select("td.trFon2")?.toString()
val year = if (!yearRes.isNullOrEmpty()) {
if (yearRes.contains("var year =")) {
yearRes = yearRes.substring(yearRes.indexOf("var year =") + "var year =".length)
//Log.i(this.name, "Result => (yearRes) $yearRes")
yearRes = yearRes.substring(0, yearRes.indexOf(';'))
.trim().removeSurrounding("'")
inner?.select("table")?.select("tr")?.forEach {
val td = it?.select("td") ?: return@forEach
val caption = td[0].text()?.lowercase()
//Log.i(this.name, "Result => (caption) $caption")
when (caption) {
"name" -> {
title = td[1].text()
}
"year" -> {
var yearRes = td[1].toString()
year = if (yearRes.isNotBlank()) {
if (yearRes.contains("var year =")) {
yearRes = yearRes.substring(yearRes.indexOf("var year =") + "var year =".length)
//Log.i(this.name, "Result => (yearRes) $yearRes")
yearRes = yearRes.substring(0, yearRes.indexOf(';'))
.trim().removeSurrounding("'")
}
yearRes.toIntOrNull()
} else { null }
}
"genre" -> {
tags = td[1].select("a")?.mapNotNull { tag ->
tag?.text()?.trim() ?: return@mapNotNull null
}?.filter { a -> a.isNotBlank() }
}
}
yearRes.toIntOrNull()
} else { null }
}
var descript = body?.select("div.eText")?.text()
if (!descript.isNullOrEmpty()) {
try {
descript = descript.substring(0, descript.indexOf("_x_Polus1"))
.replace("_x_Polus1", "")
descript = "(undefined_x_Polus+[.\\d+])".toRegex().replace(descript, "")
descript = "(_x_Polus+[.\\d+])".toRegex().replace(descript, "")
descript = descript.trim().removeSuffix("undefined").trim()
} catch (e: java.lang.Exception) { }
}
// Add links hidden in description
listOfLinks.addAll(fetchUrls(descript))
listOfLinks.forEach { link ->
//Log.i(this.name, "Result => (hidden link) $link")
descript = descript?.replace(link, "")
}
// Try looking for episodes, for series
val episodeList = ArrayList<TvSeriesEpisode>()
@ -145,22 +167,19 @@ class PinoyHDXyzProvider : MainAPI() {
}
if (episodeList.size > 0) {
return TvSeriesLoadResponse(
title,
url,
this.name,
TvType.TvSeries,
episodeList,
poster,
year,
descript,
null,
null,
null
name = title,
url = url,
apiName = this.name,
type = TvType.TvSeries,
episodes = episodeList,
posterUrl = poster,
year = year,
plot = descript,
tags = tags
)
}
// Video links for Movie
val listOfLinks: MutableList<String> = mutableListOf()
body?.select("div.tabcontent > iframe")?.forEach {
val linkMain = it?.attr("src")
if (!linkMain.isNullOrEmpty()) {
@ -181,7 +200,17 @@ class PinoyHDXyzProvider : MainAPI() {
val streamLinks = listOfLinks.distinct().toJson()
//Log.i(this.name, "Result => (streamLinks) streamLinks")
return MovieLoadResponse(title, url, this.name, TvType.Movie, streamLinks, poster, year, descript, null, null)
return MovieLoadResponse(
name = title,
url = url,
apiName = this.name,
type = TvType.Movie,
dataUrl = streamLinks,
posterUrl = poster,
year = year,
plot = descript,
tags = tags
)
}
override suspend fun loadLinks(
@ -191,11 +220,12 @@ class PinoyHDXyzProvider : MainAPI() {
callback: (ExtractorLink) -> Unit
): Boolean {
var count = 0
mapper.readValue<List<String>>(data).apmap { item ->
if (item.isNotEmpty()) {
val url = item.trim()
loadExtractor(url, mainUrl, callback)
count++
mapper.readValue<List<String>>(data).forEach { item ->
val url = item.trim()
if (url.isNotBlank()) {
if (loadExtractor(url, mainUrl, callback)) {
count++
}
}
}
return count > 0

View File

@ -113,13 +113,33 @@ class PinoyMoviePediaProvider : MainAPI() {
val isTvSeries = doc.select("title")?.text()?.lowercase()?.contains("full episode -") ?: false
// Video details
val data = inner?.select("div.data")
val poster = inner?.select("div.poster > img")?.attr("src")
val title = inner?.select("div.data > h1")?.firstOrNull()?.text() ?: ""
val descript = body?.select("div#info > div.wp-content")?.text()
val title = data?.select("h1")?.firstOrNull()?.text() ?: ""
val descript = body?.select("div#info > div.wp-content")
?.select("p")?.get(0)?.text()
val rex = Regex("\\((\\d+)")
val yearRes = rex.find(title)?.value ?: ""
//Log.i(this.name, "Result => (yearRes) ${yearRes}")
val year = yearRes.replace("(", "").toIntOrNull()
val tags = data?.select("div.sgeneros > a")?.mapNotNull { tag ->
tag?.text()?.trim() ?: return@mapNotNull null
}?.toList()
val recList = body?.select("div#single_relacionados > article")?.mapNotNull {
val a = it.select("a") ?: return@mapNotNull null
val aUrl = a.attr("href") ?: return@mapNotNull null
val aImg = a.select("img")?.attr("src")
val aName = a.select("img")?.attr("alt") ?: return@mapNotNull null
val aYear = aName.trim().takeLast(5).removeSuffix(")").toIntOrNull()
MovieSearchResponse(
url = aUrl,
name = aName,
type = TvType.Movie,
posterUrl = aImg,
year = aYear,
apiName = this.name
)
}
// Video links
val playcontainer = body?.select("div#playcontainer")
@ -162,21 +182,31 @@ class PinoyMoviePediaProvider : MainAPI() {
}
}
return TvSeriesLoadResponse(
title,
url,
this.name,
TvType.TvSeries,
episodeList,
poster,
year,
descript,
null,
null,
null
name = title,
url = url,
apiName = this.name,
type = TvType.TvSeries,
episodes = episodeList,
posterUrl = poster,
year = year,
plot = descript,
tags = tags,
recommendations = recList
)
}
val streamlinks = listOfLinks.distinct().toJson()
return MovieLoadResponse(title, url, this.name, TvType.Movie, streamlinks, poster, year, descript, null, null)
return MovieLoadResponse(
name = title,
url = url,
apiName = this.name,
type = TvType.Movie,
dataUrl = streamlinks,
posterUrl = poster,
year = year,
plot = descript,
tags = tags,
recommendations = recList
)
}
override suspend fun loadLinks(

View File

@ -29,45 +29,49 @@ class PinoyMoviesEsProvider : MainAPI() {
val all = mutableListOf<HomePageList>()
for (item in rows) {
val title = item.first
val inner = mainbody.select("div${sep}${item.second} > article")
if (inner != null) {
val elements: List<SearchResponse> = inner.map {
// Get inner div from article
var urlTitle = it?.select("div.data.dfeatur")
if (urlTitle.isNullOrEmpty()) {
urlTitle = it?.select("div.data")
}
// Fetch details
val link = urlTitle?.select("a")?.attr("href") ?: ""
val image = it?.select("div.poster > img")?.attr("data-src")
// Get Title and Year
val name = urlTitle?.select("h3")?.text() ?: ""
var year = urlTitle?.select("span")?.text()?.toIntOrNull()
if (year == null) {
// Get year from name
val rex = Regex("\\((\\d+)")
year = rex.find(name)?.value?.replace("(", "")?.toIntOrNull()
}
MovieSearchResponse(
name,
link,
this.name,
TvType.Movie,
image,
year,
null,
)
}.filter { a -> a.url.isNotEmpty() }
.filter { b -> b.name.isNotEmpty() }
.distinctBy { c -> c.url }
if (!elements.isNullOrEmpty()) {
all.add(HomePageList(
title, elements
))
val elements = mainbody.select("div${sep}${item.second} > article")?.mapNotNull {
// Get inner div from article
var urlTitle = it?.select("div.data.dfeatur")
if (urlTitle.isNullOrEmpty()) {
urlTitle = it?.select("div.data")
}
if (urlTitle.isNullOrEmpty()) { return@mapNotNull null }
// Fetch details
val link = fixUrlNull(urlTitle.select("a")?.attr("href"))
if (link.isNullOrBlank()) { return@mapNotNull null }
val image = it?.select("div.poster > img")?.attr("data-src")
// Get Title and Year
val name = urlTitle.select("h3")?.text()
?: urlTitle.select("h2")?.text()
?: urlTitle.select("h1")?.text()
if (name.isNullOrBlank()) { return@mapNotNull null }
var year = urlTitle.select("span")?.text()?.toIntOrNull()
if (year == null) {
// Get year from name
val rex = Regex("\\((\\d+)")
year = rex.find(name)?.value?.replace("(", "")?.toIntOrNull()
}
MovieSearchResponse(
name = name,
url = link,
apiName = this.name,
type = TvType.Movie,
posterUrl = image,
year = year
)
}?.distinctBy { c -> c.url } ?: listOf()
//Add to list of homepages
if (!elements.isNullOrEmpty()) {
all.add(
HomePageList(
title, elements
)
)
}
}
return all
@ -136,12 +140,30 @@ class PinoyMoviesEsProvider : MainAPI() {
val descript = body?.select("div#info > div.wp-content")?.text()
val poster = body?.select("div.poster > img")?.attr("src")
val tags = data?.select("div.sgeneros > a")?.mapNotNull { tag ->
tag?.text() ?: return@mapNotNull null
}?.toList()
val recList = body?.select("div#single_relacionados > article")?.mapNotNull {
val a = it.select("a") ?: return@mapNotNull null
val aUrl = a.attr("href") ?: return@mapNotNull null
val aImg = a.select("img")?.attr("data-src")
val aName = a.select("img")?.attr("alt") ?: return@mapNotNull null
val aYear = aName.trim().takeLast(5).removeSuffix(")").toIntOrNull()
MovieSearchResponse(
url = aUrl,
name = aName,
type = TvType.Movie,
posterUrl = aImg,
year = aYear,
apiName = this.name
)
}
// Video links
val listOfLinks: MutableList<String> = mutableListOf()
val postlist = body?.select("div#playeroptions > ul > li")?.mapNotNull {
it?.attr("data-post") ?: return@mapNotNull null
}?.filter { it.isNotEmpty() }?.distinct() ?: listOf()
}?.filter { it.isNotBlank() }?.distinct() ?: listOf()
postlist.apmap { datapost ->
//Log.i(this.name, "Result => (datapost) ${datapost}")
@ -159,7 +181,18 @@ class PinoyMoviesEsProvider : MainAPI() {
listOfLinks.add(embedData.embed_url)
}
}
return MovieLoadResponse(title, url, this.name, TvType.Movie, listOfLinks.toJson(), poster, year, descript, null, null)
return MovieLoadResponse(
name = title,
url = url,
apiName = this.name,
type = TvType.Movie,
dataUrl = listOfLinks.toJson(),
posterUrl = poster,
year = year,
plot = descript,
tags = tags,
recommendations = recList
)
}
override suspend fun loadLinks(
@ -170,19 +203,22 @@ class PinoyMoviesEsProvider : MainAPI() {
): Boolean {
// parse movie servers
var count = 0
mapper.readValue<List<String>>(data).apmap { link ->
count++
mapper.readValue<List<String>>(data).forEach { link ->
//Log.i(this.name, "Result => (link) $link")
if (link.startsWith("https://vstreamhub.com")) {
VstreamhubHelper.getUrls(link, callback)
count++
} else if (link.contains("fembed.com")) {
val extractor = FEmbed()
extractor.domainUrl = "diasfem.com"
extractor.getUrl(data).forEach {
callback.invoke(it)
count++
}
} else {
loadExtractor(link, mainUrl, callback)
if (loadExtractor(link, mainUrl, callback)) {
count++
}
}
}
return count > 0

View File

@ -98,6 +98,7 @@ class WatchAsianProvider : MainAPI() {
var title = ""
var descript : String? = null
var year : Int? = null
var tags : List<String>? = null
if (isDramaDetail) {
val main = body.select("div.details")
val inner = main?.select("div.info")
@ -105,14 +106,20 @@ class WatchAsianProvider : MainAPI() {
poster = fixUrlNull(main?.select("div.img > img")?.attr("src")) ?: ""
//Log.i(this.name, "Result => (imgLinkCode) ${imgLinkCode}")
title = inner?.select("h1")?.firstOrNull()?.text() ?: ""
year = if (title.length > 5) {
title.replace(")", "").replace("(", "").substring(title.length - 5)
.trim().trimEnd(')').toIntOrNull()
} else {
null
}
//Log.i(this.name, "Result => (year) ${title.substring(title.length - 5)}")
descript = inner?.text()
inner?.select("p")?.forEach { p ->
val caption = p?.selectFirst("span")?.text()?.trim()?.lowercase()?.removeSuffix(":")?.trim() ?: return@forEach
when (caption) {
"genre" -> {
tags = p.select("a")?.mapNotNull { it?.text()?.trim() }
}
"released" -> {
year = p.select("a")?.text()?.trim()?.toIntOrNull()
}
}
}
} else {
poster = body.select("meta[itemprop=\"image\"]")?.attr("content") ?: ""
title = body.selectFirst("div.block.watch-drama")?.selectFirst("h1")
@ -120,6 +127,13 @@ class WatchAsianProvider : MainAPI() {
year = null
descript = body.select("meta[name=\"description\"]")?.attr("content")
}
//Fallback year from title
if (year == null) {
year = if (title.length > 5) {
title.replace(")", "").replace("(", "").substring(title.length - 5)
.trim().trimEnd(')').toIntOrNull()
} else { null }
}
// Episodes Links
//Log.i(this.name, "Result => (all eps) ${body.select("ul.list-episode-item-2.all-episode > li")}")
@ -147,20 +161,28 @@ class WatchAsianProvider : MainAPI() {
title = title.trim().removeSuffix("Episode 1")
val streamlink = getServerLinks(episodeList[0].data)
//Log.i(this.name, "Result => (streamlink) $streamlink")
return MovieLoadResponse(title, url, this.name, TvType.Movie, streamlink, poster, year, descript, null, null)
return MovieLoadResponse(
name = title,
url = url,
apiName = this.name,
type = TvType.Movie,
dataUrl = streamlink,
posterUrl = poster,
year = year,
plot = descript,
tags = tags
)
}
return TvSeriesLoadResponse(
title,
url,
this.name,
TvType.TvSeries,
episodeList.reversed(),
poster,
year,
descript,
null,
null,
null
name = title,
url = url,
apiName = this.name,
type = TvType.TvSeries,
episodes = episodeList.reversed(),
posterUrl = poster,
year = year,
plot = descript,
tags = tags
)
}