2022-01-03 00:57:36 +00:00
|
|
|
package com.lagradost.cloudstream3.movieproviders
|
|
|
|
|
2022-01-11 12:36:54 +00:00
|
|
|
import com.fasterxml.jackson.module.kotlin.readValue
|
2022-01-03 00:57:36 +00:00
|
|
|
import com.lagradost.cloudstream3.*
|
2022-03-17 15:04:05 +00:00
|
|
|
import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.extractVidstream
|
2022-03-21 11:07:36 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.XStreamCdn
|
2022-01-22 14:14:47 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.helper.AsianEmbedHelper
|
2022-01-11 12:36:54 +00:00
|
|
|
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
2022-01-03 00:57:36 +00:00
|
|
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
|
|
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
|
|
|
|
|
|
|
class DramaSeeProvider : MainAPI() {
|
2022-03-16 15:29:11 +00:00
|
|
|
override var mainUrl = "https://dramasee.net"
|
|
|
|
override var name = "DramaSee"
|
2022-01-03 00:57:36 +00:00
|
|
|
override val hasQuickSearch = false
|
|
|
|
override val hasMainPage = true
|
|
|
|
override val hasChromecastSupport = false
|
2022-01-09 12:27:10 +00:00
|
|
|
override val hasDownloadSupport = true
|
2022-03-21 11:07:36 +00:00
|
|
|
override val supportedTypes = setOf(TvType.AsianDrama)
|
2022-01-03 00:57:36 +00:00
|
|
|
|
2022-01-16 22:31:42 +00:00
|
|
|
override suspend fun getMainPage(): HomePageResponse {
|
2022-01-03 00:57:36 +00:00
|
|
|
val headers = mapOf("X-Requested-By" to "dramasee.net")
|
2022-01-11 12:36:54 +00:00
|
|
|
val document = app.get(mainUrl, headers = headers).document
|
2022-01-03 00:57:36 +00:00
|
|
|
val mainbody = document.getElementsByTag("body")
|
|
|
|
|
2022-03-17 15:04:05 +00:00
|
|
|
return HomePageResponse(
|
|
|
|
mainbody?.select("section")?.map { row ->
|
|
|
|
val main = row?.select("main") ?: return@map null
|
|
|
|
val title = main.select("div.title > div > h2")?.text() ?: "Main"
|
|
|
|
val inner = main.select("li.series-item") ?: return@map null
|
2022-01-03 00:57:36 +00:00
|
|
|
|
2022-03-17 15:04:05 +00:00
|
|
|
HomePageList(
|
|
|
|
title,
|
|
|
|
inner.mapNotNull {
|
|
|
|
// Get inner div from article
|
|
|
|
val innerBody = it?.selectFirst("a")
|
|
|
|
// Fetch details
|
|
|
|
val link = fixUrlNull(innerBody?.attr("href")) ?: return@mapNotNull null
|
|
|
|
val image = fixUrlNull(innerBody?.select("img")?.attr("src")) ?: ""
|
|
|
|
val name = it?.selectFirst("a.series-name")?.text() ?: "<Untitled>"
|
|
|
|
//Log.i(this.name, "Result => (innerBody, image) ${innerBody} / ${image}")
|
|
|
|
MovieSearchResponse(
|
|
|
|
name,
|
|
|
|
link,
|
|
|
|
this.name,
|
2022-03-21 11:07:36 +00:00
|
|
|
TvType.AsianDrama,
|
2022-03-17 15:04:05 +00:00
|
|
|
image,
|
|
|
|
year = null,
|
|
|
|
id = null,
|
|
|
|
)
|
|
|
|
}.distinctBy { c -> c.url })
|
2022-01-03 00:57:36 +00:00
|
|
|
}?.filterNotNull() ?: listOf()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-01-16 22:31:42 +00:00
|
|
|
override suspend fun search(query: String): List<SearchResponse> {
|
2022-01-03 00:57:36 +00:00
|
|
|
val url = "$mainUrl/search?q=$query"
|
|
|
|
val html = app.get(url).document
|
|
|
|
val document = html.getElementsByTag("body")
|
2022-03-17 15:04:05 +00:00
|
|
|
.select("section > main > ul.series > li") ?: return listOf()
|
2022-01-03 00:57:36 +00:00
|
|
|
|
2022-01-11 12:36:54 +00:00
|
|
|
return document.mapNotNull {
|
|
|
|
if (it == null) {
|
|
|
|
return@mapNotNull null
|
|
|
|
}
|
|
|
|
val innerA = it.select("a.series-img") ?: return@mapNotNull null
|
|
|
|
val link = fixUrlNull(innerA.attr("href")) ?: return@mapNotNull null
|
|
|
|
val title = it.select("a.series-name")?.text() ?: return@mapNotNull null
|
2022-01-03 00:57:36 +00:00
|
|
|
val year = null
|
2022-01-11 12:36:54 +00:00
|
|
|
val imgsrc = innerA.select("img")?.attr("src") ?: return@mapNotNull null
|
|
|
|
val image = fixUrlNull(imgsrc)
|
2022-01-03 00:57:36 +00:00
|
|
|
|
|
|
|
MovieSearchResponse(
|
2022-01-11 12:36:54 +00:00
|
|
|
name = title,
|
|
|
|
url = link,
|
|
|
|
apiName = this.name,
|
|
|
|
type = TvType.Movie,
|
|
|
|
posterUrl = image,
|
|
|
|
year = year
|
2022-01-03 00:57:36 +00:00
|
|
|
)
|
2022-01-11 12:36:54 +00:00
|
|
|
}
|
2022-01-03 00:57:36 +00:00
|
|
|
}
|
|
|
|
|
2022-01-16 22:31:42 +00:00
|
|
|
override suspend fun load(url: String): LoadResponse {
|
2022-01-03 00:57:36 +00:00
|
|
|
val doc = app.get(url).document
|
|
|
|
val body = doc.getElementsByTag("body")
|
|
|
|
val inner = body?.select("div.series-info")
|
|
|
|
|
|
|
|
// Video details
|
|
|
|
val poster = fixUrlNull(inner?.select("div.img > img")?.attr("src")) ?: ""
|
|
|
|
//Log.i(this.name, "Result => (imgLinkCode) ${imgLinkCode}")
|
|
|
|
val title = inner?.select("h1.series-name")?.text() ?: ""
|
2022-03-17 15:04:05 +00:00
|
|
|
val year = if (title.length > 5) {
|
|
|
|
title.substring(title.length - 5)
|
|
|
|
.trim().trimEnd(')').toIntOrNull()
|
|
|
|
} else {
|
|
|
|
null
|
|
|
|
}
|
2022-01-03 00:57:36 +00:00
|
|
|
//Log.i(this.name, "Result => (year) ${title.substring(title.length - 5)}")
|
2022-02-06 11:43:12 +00:00
|
|
|
val seriesBody = body?.select("div.series-body")
|
|
|
|
val descript = seriesBody?.firstOrNull()?.select("div.js-content")?.text()
|
2022-03-17 15:04:05 +00:00
|
|
|
val tags = seriesBody?.select("div.series-tags > a")
|
|
|
|
?.mapNotNull { it?.text()?.trim() ?: return@mapNotNull null }
|
2022-02-06 11:43:12 +00:00
|
|
|
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
|
|
|
|
)
|
|
|
|
}
|
2022-01-03 00:57:36 +00:00
|
|
|
|
|
|
|
// Episodes Links
|
2022-04-09 14:50:04 +00:00
|
|
|
val episodeList = ArrayList<Episode>()
|
2022-01-31 21:01:25 +00:00
|
|
|
body?.select("ul.episodes > li")?.forEach { ep ->
|
2022-01-11 12:36:54 +00:00
|
|
|
val innerA = ep.select("a") ?: return@forEach
|
|
|
|
val count = innerA.select("span.episode")?.text()?.toIntOrNull() ?: 0
|
|
|
|
val epLink = fixUrlNull(innerA.attr("href")) ?: return@forEach
|
|
|
|
//Log.i(this.name, "Result => (epLink) ${epLink}")
|
2022-02-06 11:43:12 +00:00
|
|
|
if (epLink.isNotBlank()) {
|
2022-01-11 12:36:54 +00:00
|
|
|
// Fetch video links
|
|
|
|
val epVidLinkEl = app.get(epLink, referer = mainUrl).document
|
|
|
|
val ajaxUrl = epVidLinkEl.select("div#js-player")?.attr("embed")
|
|
|
|
//Log.i(this.name, "Result => (ajaxUrl) ${ajaxUrl}")
|
|
|
|
if (!ajaxUrl.isNullOrEmpty()) {
|
|
|
|
val innerPage = app.get(fixUrl(ajaxUrl), referer = epLink).document
|
|
|
|
val listOfLinks = mutableListOf<String>()
|
|
|
|
innerPage.select("div.player.active > main > div")?.forEach { em ->
|
2022-01-31 21:01:25 +00:00
|
|
|
val href = fixUrlNull(em.attr("src")) ?: ""
|
2022-02-06 11:43:12 +00:00
|
|
|
if (href.isNotBlank()) {
|
2022-01-11 12:36:54 +00:00
|
|
|
listOfLinks.add(href)
|
2022-01-03 00:57:36 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-11 12:36:54 +00:00
|
|
|
|
2022-01-31 21:01:25 +00:00
|
|
|
//Log.i(this.name, "Result => (listOfLinks) ${listOfLinks.toJson()}")
|
2022-01-11 12:36:54 +00:00
|
|
|
episodeList.add(
|
2022-04-09 14:50:04 +00:00
|
|
|
Episode(
|
2022-01-11 12:36:54 +00:00
|
|
|
name = null,
|
|
|
|
season = null,
|
|
|
|
episode = count,
|
|
|
|
data = listOfLinks.distinct().toJson(),
|
|
|
|
posterUrl = poster,
|
|
|
|
date = null
|
|
|
|
)
|
|
|
|
)
|
2022-01-03 00:57:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-11 12:36:54 +00:00
|
|
|
|
2022-01-03 00:57:36 +00:00
|
|
|
//If there's only 1 episode, consider it a movie.
|
|
|
|
if (episodeList.size == 1) {
|
2022-02-06 11:43:12 +00:00
|
|
|
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
|
|
|
|
)
|
2022-01-03 00:57:36 +00:00
|
|
|
}
|
|
|
|
return TvSeriesLoadResponse(
|
2022-02-06 11:43:12 +00:00
|
|
|
name = title,
|
|
|
|
url = url,
|
|
|
|
apiName = this.name,
|
2022-03-21 11:07:36 +00:00
|
|
|
type = TvType.AsianDrama,
|
2022-02-06 11:43:12 +00:00
|
|
|
episodes = episodeList.reversed(),
|
|
|
|
posterUrl = poster,
|
|
|
|
year = year,
|
|
|
|
plot = descript,
|
|
|
|
recommendations = recs,
|
|
|
|
tags = tags
|
2022-01-03 00:57:36 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-01-16 22:31:42 +00:00
|
|
|
override suspend fun loadLinks(
|
2022-01-03 00:57:36 +00:00
|
|
|
data: String,
|
|
|
|
isCasting: Boolean,
|
|
|
|
subtitleCallback: (SubtitleFile) -> Unit,
|
|
|
|
callback: (ExtractorLink) -> Unit
|
|
|
|
): Boolean {
|
2022-01-22 14:14:47 +00:00
|
|
|
var count = 0
|
2022-01-30 01:50:49 +00:00
|
|
|
mapper.readValue<List<String>>(data).apmap { item ->
|
2022-01-11 12:36:54 +00:00
|
|
|
if (item.isNotEmpty()) {
|
2022-01-22 14:14:47 +00:00
|
|
|
count++
|
2022-01-31 21:01:25 +00:00
|
|
|
val url = fixUrl(item.trim())
|
2022-01-11 12:36:54 +00:00
|
|
|
//Log.i(this.name, "Result => (url) ${url}")
|
2022-01-22 14:14:47 +00:00
|
|
|
when {
|
2022-01-31 21:01:25 +00:00
|
|
|
url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> {
|
2022-04-17 14:26:51 +00:00
|
|
|
val iv = "9262859232435825"
|
|
|
|
val secretKey = "93422192433952489752342908585752"
|
2022-04-30 13:02:36 +00:00
|
|
|
extractVidstream(url, this.name, callback, iv, secretKey, secretKey,
|
|
|
|
isUsingAdaptiveKeys = false,
|
|
|
|
isUsingAdaptiveData = false
|
|
|
|
)
|
2022-01-22 14:14:47 +00:00
|
|
|
AsianEmbedHelper.getUrls(url, callback)
|
|
|
|
}
|
|
|
|
url.startsWith("https://embedsito.com") -> {
|
|
|
|
val extractor = XStreamCdn()
|
|
|
|
extractor.domainUrl = "embedsito.com"
|
2022-01-31 21:01:25 +00:00
|
|
|
extractor.getSafeUrl(url)?.forEach(callback)
|
2022-01-11 12:36:54 +00:00
|
|
|
}
|
2022-01-22 14:14:47 +00:00
|
|
|
else -> {
|
|
|
|
loadExtractor(url, mainUrl, callback)
|
2022-01-11 12:36:54 +00:00
|
|
|
}
|
2022-01-22 14:14:47 +00:00
|
|
|
}
|
2022-01-03 00:57:36 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-22 14:14:47 +00:00
|
|
|
return count > 0
|
2022-01-03 00:57:36 +00:00
|
|
|
}
|
2022-01-31 21:01:25 +00:00
|
|
|
}
|