This commit is contained in:
LagradOst 2021-07-23 18:41:37 +02:00
parent be714a9a26
commit 3551cb1c67
17 changed files with 203 additions and 314 deletions

3
.idea/.gitignore vendored
View file

@ -1,3 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-11" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />

View file

@ -24,12 +24,12 @@
<remote-repository> <remote-repository>
<option name="id" value="maven" /> <option name="id" value="maven" />
<option name="name" value="maven" /> <option name="name" value="maven" />
<option name="url" value="https://jitpack.io" /> <option name="url" value="https://github.com/psiegman/mvn-repo/raw/master/releases" />
</remote-repository> </remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="maven" /> <option name="id" value="maven2" />
<option name="name" value="maven" /> <option name="name" value="maven2" />
<option name="url" value="https://github.com/psiegman/mvn-repo/raw/master/releases" /> <option name="url" value="https://jitpack.io" />
</remote-repository> </remote-repository>
</component> </component>
</project> </project>

View file

@ -1,9 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK"> <component name="ExternalStorageConfigurationManager" enabled="true" />
<output url="file://$PROJECT_DIR$/build/classes" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project> </project>

View file

@ -1,124 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="" vcs="Git" />
</component> </component>
</project> </project>

View file

@ -1,31 +1,24 @@
package com.lagradost.cloudstream3.animeproviders package com.lagradost.cloudstream3.animeproviders
import android.annotation.SuppressLint import android.annotation.SuppressLint
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.module.kotlin.readValue
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.extractors.Vidstream
import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.getQualityFromName
import khttp.structures.cookie.CookieJar
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import java.util.*
import kotlin.collections.ArrayList
import khttp.structures.cookie.CookieJar
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.*
class TenshiProvider : MainAPI() { class TenshiProvider : MainAPI() {
companion object { companion object {
var token: String? = null var token: String? = null
var cookie: CookieJar? = null var cookie: CookieJar? = null
fun getType(t: String): TvType { fun getType(t: String): TvType {
if (t.contains("OVA") || t.contains("Special")) return TvType.ONA return if (t.contains("OVA") || t.contains("Special")) TvType.ONA
else if (t.contains("Movie")) return TvType.Movie else if (t.contains("Movie")) TvType.Movie
else return TvType.Anime else TvType.Anime
} }
} }
@ -43,9 +36,7 @@ class TenshiProvider : MainAPI() {
private fun loadToken(): Boolean { private fun loadToken(): Boolean {
return try { return try {
val response = khttp.get( val response = khttp.get(mainUrl)
"https://tenshi.moe/",
)
cookie = response.cookies cookie = response.cookies
val document = Jsoup.parse(response.text) val document = Jsoup.parse(response.text)
token = document.selectFirst("""meta[name="csrf-token"]""").attr("content") token = document.selectFirst("""meta[name="csrf-token"]""").attr("content")
@ -179,7 +170,7 @@ class TenshiProvider : MainAPI() {
return returnValue return returnValue
} }
override fun load(slug: String): LoadResponse? { override fun load(slug: String): LoadResponse {
val url = "$mainUrl/anime/${slug}" val url = "$mainUrl/anime/${slug}"
val response = khttp.get(url, timeout = 120.0, cookies=mapOf("loop-view" to "thumb")) val response = khttp.get(url, timeout = 120.0, cookies=mapOf("loop-view" to "thumb"))
@ -189,7 +180,6 @@ class TenshiProvider : MainAPI() {
val japaneseTitle = document.selectFirst("span.value > span[title=\"Japanese\"]")?.parent()?.text()?.trim() val japaneseTitle = document.selectFirst("span.value > span[title=\"Japanese\"]")?.parent()?.text()?.trim()
val canonicalTitle = document.selectFirst("header.entry-header > h1.mb-3").text().trim() val canonicalTitle = document.selectFirst("header.entry-header > h1.mb-3").text().trim()
val isDubbed = false
val episodeNodes = document.select("li[class*=\"episode\"] > a") val episodeNodes = document.select("li[class*=\"episode\"] > a")
val episodes = ArrayList<AnimeEpisode>(episodeNodes?.map { val episodes = ArrayList<AnimeEpisode>(episodeNodes?.map {
@ -212,7 +202,7 @@ class TenshiProvider : MainAPI() {
val (year) = pattern.find(yearText)!!.destructured val (year) = pattern.find(yearText)!!.destructured
val poster = document.selectFirst("img.cover-image")?.attr("src") val poster = document.selectFirst("img.cover-image")?.attr("src")
val type = document.selectFirst("a[href*=\"https://tenshi.moe/type/\"]")?.text()?.trim() val type = document.selectFirst("a[href*=\"$mainUrl/type/\"]")?.text()?.trim()
val synopsis = document.selectFirst(".entry-description > .card-body")?.text()?.trim() val synopsis = document.selectFirst(".entry-description > .card-body")?.text()?.trim()
val genre = document.select("li.genre.meta-data > span.value").map { it?.text()?.trim().toString() } val genre = document.select("li.genre.meta-data > span.value").map { it?.text()?.trim().toString() }
@ -232,7 +222,7 @@ class TenshiProvider : MainAPI() {
episodes, episodes,
status, status,
synopsis, synopsis,
ArrayList(genre) ?: ArrayList(), ArrayList(genre),
ArrayList(synonyms), ArrayList(synonyms),
null, null,
null, null,

View file

@ -10,7 +10,6 @@ import kotlin.collections.ArrayList
class WcoProvider : MainAPI() { class WcoProvider : MainAPI() {
companion object { companion object {
fun getType(t: String): TvType { fun getType(t: String): TvType {
return if (t.contains("OVA") || t.contains("Special")) TvType.ONA return if (t.contains("OVA") || t.contains("Special")) TvType.ONA
@ -137,7 +136,7 @@ class WcoProvider : MainAPI() {
return returnValue return returnValue
} }
override fun load(slug: String): LoadResponse? { override fun load(slug: String): LoadResponse {
val url = "$mainUrl/anime/${slug}" val url = "$mainUrl/anime/${slug}"
val response = khttp.get(url, timeout = 120.0) val response = khttp.get(url, timeout = 120.0)
@ -177,11 +176,11 @@ class WcoProvider : MainAPI() {
canonicalTitle, canonicalTitle,
"$mainUrl/anime/${slug}", "$mainUrl/anime/${slug}",
this.name, this.name,
WcoProvider.getType(type ?: ""), getType(type ?: ""),
poster, poster,
year, year,
null, if(isDubbed) episodes else null,
episodes, if(!isDubbed) episodes else null,
status, status,
synopsis, synopsis,
ArrayList(genre), ArrayList(genre),
@ -204,7 +203,7 @@ class WcoProvider : MainAPI() {
} }
for (server in servers) { for (server in servers) {
WcoStream().getUrl(server["link"].toString(), "").forEach { WcoStream().getSafeUrl(server["link"].toString(), "")?.forEach {
callback.invoke(it) callback.invoke(it)
} }
} }

View file

@ -1,11 +1,7 @@
package com.lagradost.cloudstream3.utils package com.lagradost.cloudstream3.utils
import com.lagradost.cloudstream3.utils.extractors.MixDrop import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.utils.extractors.Mp4Upload import com.lagradost.cloudstream3.utils.extractors.*
import com.lagradost.cloudstream3.utils.extractors.Shiro
import com.lagradost.cloudstream3.utils.extractors.WcoStream
import com.lagradost.cloudstream3.utils.extractors.StreamTape
import com.lagradost.cloudstream3.utils.extractors.XStreamCdn
data class ExtractorLink( data class ExtractorLink(
val source: String, val source: String,
@ -59,7 +55,8 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
Mp4Upload(), Mp4Upload(),
StreamTape(), StreamTape(),
MixDrop(), MixDrop(),
XStreamCdn() XStreamCdn(),
StreamSB(),
) )
fun getExtractorApiFromName(name: String): ExtractorApi { fun getExtractorApiFromName(name: String): ExtractorApi {
@ -82,6 +79,13 @@ abstract class ExtractorApi {
abstract val mainUrl: String abstract val mainUrl: String
abstract val requiresReferer: Boolean abstract val requiresReferer: Boolean
fun getSafeUrl(url: String, referer: String? = null): List<ExtractorLink>? {
return normalSafeApiCall { getUrl(url, referer) }
}
/**
* Will throw errors, use getSafeUrl if you don't want to handle the exception yourself
*/
abstract fun getUrl(url: String, referer: String? = null): List<ExtractorLink>? abstract fun getUrl(url: String, referer: String? = null): List<ExtractorLink>?
open fun getExtractorUrl(id: String): String { open fun getExtractorUrl(id: String): String {

View file

@ -13,25 +13,21 @@ class MixDrop : ExtractorApi() {
} }
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
try { with(khttp.get(url)) {
with(khttp.get(url)) { getAndUnpack(this.text)?.let { unpackedText ->
getAndUnpack(this.text)?.let { unpackedText -> srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link ->
srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> return listOf(
return listOf( ExtractorLink(
ExtractorLink( name,
name, name,
name, httpsify(link),
httpsify(link), url,
url, Qualities.Unknown.value,
Qualities.Unknown.value,
)
) )
} )
} }
} }
return null
} catch (e: Exception) {
return null
} }
return null
} }
} }

View file

@ -9,25 +9,21 @@ class Mp4Upload : ExtractorApi() {
override val requiresReferer = true override val requiresReferer = true
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
try { with(khttp.get(url)) {
with(khttp.get(url)) { getAndUnpack(this.text)?.let { unpackedText ->
getAndUnpack(this.text)?.let { unpackedText -> srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link ->
srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> return listOf(
return listOf( ExtractorLink(
ExtractorLink( name,
name, name,
name, link,
link, url,
url, Qualities.Unknown.value,
Qualities.Unknown.value,
)
) )
} )
} }
} }
return null
} catch (e: Exception) {
return null
} }
return null
} }
} }

View file

@ -27,44 +27,40 @@ class MultiQuality : ExtractorApi() {
} }
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
try { val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() with(khttp.get(url)) {
with(khttp.get(url)) { sourceRegex.findAll(this.text).forEach { sourceMatch ->
sourceRegex.findAll(this.text).forEach { sourceMatch -> val extractedUrl = sourceMatch.groupValues[1]
val extractedUrl = sourceMatch.groupValues[1] // Trusting this isn't mp4, may fuck up stuff
// Trusting this isn't mp4, may fuck up stuff if (extractedUrl.endsWith(".m3u8")) {
if (extractedUrl.endsWith(".m3u8")) { with(khttp.get(extractedUrl)) {
with(khttp.get(extractedUrl)) { m3u8Regex.findAll(this.text).forEach { match ->
m3u8Regex.findAll(this.text).forEach { match -> extractedLinksList.add(
extractedLinksList.add( ExtractorLink(
ExtractorLink( name,
name, "$name ${match.groupValues[1]}p",
"$name ${match.groupValues[1]}p", urlRegex.find(this.url)!!.groupValues[1] + match.groupValues[0],
urlRegex.find(this.url)!!.groupValues[1] + match.groupValues[0], url,
url, getQuality(match.groupValues[1]),
getQuality(match.groupValues[1]), isM3u8 = true
isM3u8 = true
)
) )
}
}
} else if (extractedUrl.endsWith(".mp4")) {
extractedLinksList.add(
ExtractorLink(
name,
"$name ${sourceMatch.groupValues[2]}",
extractedUrl,
url.replace(" ", "%20"),
Qualities.Unknown.value,
) )
) }
}
}
return extractedLinksList
}
} catch (e: Exception) {
}
} else if (extractedUrl.endsWith(".mp4")) {
extractedLinksList.add(
ExtractorLink(
name,
"$name ${sourceMatch.groupValues[2]}",
extractedUrl,
url.replace(" ", "%20"),
Qualities.Unknown.value,
)
)
}
}
return extractedLinksList
} }
return null return null
} }

View file

@ -0,0 +1,51 @@
package com.lagradost.cloudstream3.utils.extractors
import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getAndUnpack
import com.lagradost.cloudstream3.utils.getQualityFromName
class StreamSB : ExtractorApi() {
override val name: String = "StreamSB"
override val mainUrl: String = "https://sbplay.org"
private val sourceRegex = Regex("""sources:[\W\w]*?file:\s*"(.*?)"""")
//private val m3u8Regex = Regex(""".*?(\d*).m3u8""")
//private val urlRegex = Regex("""(.*?)([^/]+$)""")
// 1: Resolution 2: url
private val m3u8UrlRegex = Regex("""RESOLUTION=\d*x(\d*).*\n(http.*.m3u8)""")
override val requiresReferer = false
// https://sbembed.com/embed-ns50b0cukf9j.html -> https://sbvideo.net/play/ns50b0cukf9j
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
val newUrl = url.replace("sbplay.org/embed-", "sbplay.org/play/").removeSuffix(".html")
with(khttp.get(newUrl, timeout = 10.0)) {
getAndUnpack(this.text)?.let {
sourceRegex.findAll(it).forEach { sourceMatch ->
val extractedUrl = sourceMatch.groupValues[1]
if (extractedUrl.contains(".m3u8")) {
with(khttp.get(extractedUrl)) {
m3u8UrlRegex.findAll(this.text).forEach { match ->
val extractedUrlM3u8 = match.groupValues[2]
val extractedRes = match.groupValues[1]
extractedLinksList.add(
ExtractorLink(
name,
"$name ${extractedRes}p",
extractedUrlM3u8,
extractedUrl,
getQualityFromName(extractedRes),
true
)
)
}
}
}
}
}
}
return extractedLinksList
}
}

View file

@ -14,22 +14,19 @@ class StreamTape : ExtractorApi() {
Regex("""(i(|" \+ ')d(|" \+ ')=.*?&(|" \+ ')e(|" \+ ')x(|" \+ ')p(|" \+ ')i(|" \+ ')r(|" \+ ')e(|" \+ ')s(|" \+ ')=.*?&(|" \+ ')i(|" \+ ')p(|" \+ ')=.*?&(|" \+ ')t(|" \+ ')o(|" \+ ')k(|" \+ ')e(|" \+ ')n(|" \+ ')=.*)'""") Regex("""(i(|" \+ ')d(|" \+ ')=.*?&(|" \+ ')e(|" \+ ')x(|" \+ ')p(|" \+ ')i(|" \+ ')r(|" \+ ')e(|" \+ ')s(|" \+ ')=.*?&(|" \+ ')i(|" \+ ')p(|" \+ ')=.*?&(|" \+ ')t(|" \+ ')o(|" \+ ')k(|" \+ ')e(|" \+ ')n(|" \+ ')=.*)'""")
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
try { with(khttp.get(url)) {
with(khttp.get(url)) { linkRegex.find(this.text)?.let {
linkRegex.find(this.text)?.let { val extractedUrl = "https://streamtape.com/get_video?${it.groupValues[1]}".replace("""" + '""", "")
val extractedUrl = "https://streamtape.com/get_video?${it.groupValues[1]}".replace("""" + '""", "") return listOf(
return listOf( ExtractorLink(
ExtractorLink( name,
name, name,
name, extractedUrl,
extractedUrl, url,
url, Qualities.Unknown.value,
Qualities.Unknown.value,
)
) )
} )
} }
} catch (e: Exception) {
} }
return null return null
} }

View file

@ -20,7 +20,7 @@ class Vidstream {
try { try {
normalApis.pmap { api -> normalApis.pmap { api ->
val url = api.getExtractorUrl(id) val url = api.getExtractorUrl(id)
val source = api.getUrl(url) val source = api.getSafeUrl(url)
source?.forEach { callback.invoke(it) } source?.forEach { callback.invoke(it) }
} }
@ -38,7 +38,7 @@ class Vidstream {
// Matches vidstream links with extractors // Matches vidstream links with extractors
extractorApis.filter { !it.requiresReferer || !isCasting }.pmap { api -> extractorApis.filter { !it.requiresReferer || !isCasting }.pmap { api ->
if (link.startsWith(api.mainUrl)) { if (link.startsWith(api.mainUrl)) {
val extractedLinks = api.getUrl(link, url) val extractedLinks = api.getSafeUrl(link, url)
if (extractedLinks?.isNotEmpty() == true) { if (extractedLinks?.isNotEmpty() == true) {
extractedLinks.forEach { extractedLinks.forEach {
callback.invoke(it) callback.invoke(it)

View file

@ -11,52 +11,48 @@ class WcoStream : ExtractorApi() {
override val requiresReferer = false override val requiresReferer = false
override fun getUrl(url: String, referer: String?): List<ExtractorLink> { override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
try { val baseUrl = url.split("/e/")[0]
val baseUrl = url.split("/e/")[0]
val html = khttp.get(url, headers=mapOf("Referer" to "https://wcostream.cc/")).text val html = khttp.get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text
val (Id) = "/e/(.*?)?domain".toRegex().find(url)!!.destructured val (Id) = "/e/(.*?)?domain".toRegex().find(url)!!.destructured
val (skey) = """skey\s=\s['\"](.*?)['\"];""".toRegex().find(html)!!.destructured val (skey) = """skey\s=\s['\"](.*?)['\"];""".toRegex().find(html)!!.destructured
val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey" val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey"
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc" val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
val response = khttp.get(apiLink, headers=mapOf("Referer" to referrer)).text val response = khttp.get(apiLink, headers = mapOf("Referer" to referrer)).text
data class Sources ( data class Sources(
@JsonProperty("file") val file : String, @JsonProperty("file") val file: String,
@JsonProperty("label") val label : String @JsonProperty("label") val label: String?
) )
data class Media ( data class Media(
@JsonProperty("sources") val sources : List<Sources> @JsonProperty("sources") val sources: List<Sources>
) )
data class WcoResponse ( data class WcoResponse(
@JsonProperty("success") val success : Boolean, @JsonProperty("success") val success: Boolean,
@JsonProperty("media") val media : Media @JsonProperty("media") val media: Media
) )
val mapped = response.let { mapper.readValue<WcoResponse>(it) } val mapped = response.let { mapper.readValue<WcoResponse>(it) }
val sources = mutableListOf<ExtractorLink>() val sources = mutableListOf<ExtractorLink>()
if (mapped.success) { if (mapped.success) {
mapped.media.sources.forEach { mapped.media.sources.forEach {
sources.add( sources.add(
ExtractorLink( ExtractorLink(
"WcoStream", name,
"WcoStream" + "- ${it.label}", name + if (it.label != null) "- ${it.label}" else "",
it.file, it.file,
"", "",
Qualities.HD.value, Qualities.HD.value,
it.file.contains(".m3u8") it.file.contains(".m3u8")
)
) )
} )
} }
return sources
} catch (e: Exception) {
return listOf()
} }
return sources
} }
} }

View file

@ -38,34 +38,29 @@ class XStreamCdn : ExtractorApi() {
} }
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
try { val headers = mapOf(
val headers = mapOf( "Referer" to url,
"Referer" to url, "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0",
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0", )
) val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/")
val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/") val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() with(khttp.post(newUrl, headers = headers)) {
with(khttp.post(newUrl, headers = headers)) { mapper.readValue<ResponseJson?>(this.text)?.let {
mapper.readValue<ResponseJson?>(this.text)?.let { if (it.success && it.data != null) {
if (it.success && it.data != null) { it.data.forEach { data ->
it.data.forEach { data -> extractedLinksList.add(
extractedLinksList.add( ExtractorLink(
ExtractorLink( name,
name, "$name ${data.label}",
"$name ${data.label}", data.file,
data.file, url,
url, getQuality(data.label),
getQuality(data.label),
)
) )
} )
} }
} }
} }
return extractedLinksList
} catch (e: Exception) {
} }
return null return extractedLinksList
} }
} }