forked from recloudstream/cloudstream
Merge branch 'my-temporary-work'
fuck git
This commit is contained in:
commit
42fe04a0b0
18 changed files with 440 additions and 272 deletions
3
.idea/.gitignore
vendored
3
.idea/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
|
@ -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$" />
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
|
@ -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>
|
|
@ -8,6 +8,7 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
import com.lagradost.cloudstream3.animeproviders.DubbedAnimeProvider
|
import com.lagradost.cloudstream3.animeproviders.DubbedAnimeProvider
|
||||||
import com.lagradost.cloudstream3.animeproviders.ShiroProvider
|
import com.lagradost.cloudstream3.animeproviders.ShiroProvider
|
||||||
import com.lagradost.cloudstream3.animeproviders.TenshiProvider
|
import com.lagradost.cloudstream3.animeproviders.TenshiProvider
|
||||||
|
import com.lagradost.cloudstream3.animeproviders.WcoProvider
|
||||||
import com.lagradost.cloudstream3.movieproviders.HDMProvider
|
import com.lagradost.cloudstream3.movieproviders.HDMProvider
|
||||||
import com.lagradost.cloudstream3.movieproviders.LookMovieProvider
|
import com.lagradost.cloudstream3.movieproviders.LookMovieProvider
|
||||||
import com.lagradost.cloudstream3.movieproviders.MeloMovieProvider
|
import com.lagradost.cloudstream3.movieproviders.MeloMovieProvider
|
||||||
|
@ -33,6 +34,7 @@ object APIHolder {
|
||||||
val apis = arrayListOf(
|
val apis = arrayListOf(
|
||||||
ShiroProvider(),
|
ShiroProvider(),
|
||||||
TenshiProvider(),
|
TenshiProvider(),
|
||||||
|
WcoProvider(),
|
||||||
MeloMovieProvider(),
|
MeloMovieProvider(),
|
||||||
DubbedAnimeProvider(),
|
DubbedAnimeProvider(),
|
||||||
HDMProvider(),
|
HDMProvider(),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -0,0 +1,212 @@
|
||||||
|
package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.extractors.WcoStream
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
|
||||||
|
class WcoProvider : MainAPI() {
|
||||||
|
companion object {
|
||||||
|
fun getType(t: String): TvType {
|
||||||
|
return if (t.contains("OVA") || t.contains("Special")) TvType.ONA
|
||||||
|
else if (t.contains("Movie")) TvType.Movie
|
||||||
|
else TvType.Anime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val mainUrl: String
|
||||||
|
get() = "https://wcostream.cc"
|
||||||
|
override val name: String
|
||||||
|
get() = "WCO Stream"
|
||||||
|
override val hasQuickSearch: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
|
||||||
|
private fun getSlug(href: String): String {
|
||||||
|
return href.replace("$mainUrl/anime/", "").replace("/", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fixAnimeLink(url: String): String {
|
||||||
|
val regex = "watch/([a-zA-Z\\-0-9]*)-episode".toRegex()
|
||||||
|
val (aniId) = regex.find(url)!!.destructured
|
||||||
|
return "$mainUrl/anime/$aniId"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseSearchPage(soup: Document): ArrayList<SearchResponse> {
|
||||||
|
val items = soup.select(".film_list-wrap > .flw-item")
|
||||||
|
if (items.isEmpty()) return ArrayList()
|
||||||
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
for (i in items) {
|
||||||
|
val href = fixAnimeLink(i.selectFirst("a").attr("href"))
|
||||||
|
val img = fixUrl(i.selectFirst("img").attr("data-src"))
|
||||||
|
val title = i.selectFirst("img").attr("title")
|
||||||
|
val isDub = !i.select(".pick.film-poster-quality").isEmpty()
|
||||||
|
val year = i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(1)").text().toIntOrNull()
|
||||||
|
val type = i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)").text()
|
||||||
|
|
||||||
|
returnValue.add(
|
||||||
|
if (getType(type) == TvType.Movie) {
|
||||||
|
MovieSearchResponse(
|
||||||
|
title, href, getSlug(href), this.name, TvType.Movie, img, year
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
AnimeSearchResponse(
|
||||||
|
title,
|
||||||
|
href,
|
||||||
|
getSlug(href),
|
||||||
|
this.name,
|
||||||
|
TvType.Anime,
|
||||||
|
img,
|
||||||
|
year,
|
||||||
|
null,
|
||||||
|
EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return returnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun search(query: String): ArrayList<SearchResponse> {
|
||||||
|
val url = "$mainUrl/search"
|
||||||
|
val response = khttp.get(url, params=mapOf("keyword" to query))
|
||||||
|
var document = Jsoup.parse(response.text)
|
||||||
|
val returnValue = parseSearchPage(document)
|
||||||
|
|
||||||
|
while (!document.select(".pagination").isEmpty()) {
|
||||||
|
val link = document.select("a.page-link[rel=\"next\"]")
|
||||||
|
if (!link.isEmpty()) {
|
||||||
|
val extraResponse = khttp.get(fixUrl(link[0].attr("href")))
|
||||||
|
document = Jsoup.parse(extraResponse.text)
|
||||||
|
returnValue.addAll(parseSearchPage(document))
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun quickSearch(query: String): ArrayList<SearchResponse> {
|
||||||
|
val returnValue: ArrayList<SearchResponse> = ArrayList()
|
||||||
|
|
||||||
|
val response = khttp.post(
|
||||||
|
"https://wcostream.cc/ajax/search",
|
||||||
|
data=mapOf("keyword" to query)
|
||||||
|
).jsonObject.getString("html") // I won't make a dataclass for this shit
|
||||||
|
val document = Jsoup.parse(response)
|
||||||
|
|
||||||
|
document.select("a.nav-item").forEach {
|
||||||
|
val title = it.selectFirst("img")?.attr("title").toString()
|
||||||
|
val img = it?.selectFirst("img")?.attr("src")
|
||||||
|
val href = it?.attr("href").toString()
|
||||||
|
val isDub = title.contains("(Dub)")
|
||||||
|
val filmInfo = it?.selectFirst(".film-infor")
|
||||||
|
val year = filmInfo?.select("span")?.get(0)?.text()?.toIntOrNull()
|
||||||
|
val type = filmInfo?.select("span")?.get(1)?.text().toString()
|
||||||
|
if (title != "null") {
|
||||||
|
returnValue.add(
|
||||||
|
if (getType(type) == TvType.Movie) {
|
||||||
|
MovieSearchResponse(
|
||||||
|
title, href, getSlug(href), this.name, TvType.Movie, img, year
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
AnimeSearchResponse(
|
||||||
|
title,
|
||||||
|
href,
|
||||||
|
getSlug(href),
|
||||||
|
this.name,
|
||||||
|
TvType.Anime,
|
||||||
|
img,
|
||||||
|
year,
|
||||||
|
null,
|
||||||
|
EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(slug: String): LoadResponse {
|
||||||
|
val url = "$mainUrl/anime/${slug}"
|
||||||
|
|
||||||
|
val response = khttp.get(url, timeout = 120.0)
|
||||||
|
val document = Jsoup.parse(response.text)
|
||||||
|
|
||||||
|
val japaneseTitle = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(1)")
|
||||||
|
?.text()?.trim()?.replace("Other names:", "")?.trim()
|
||||||
|
|
||||||
|
val canonicalTitle = document.selectFirst("meta[name=\"title\"]")
|
||||||
|
?.attr("content")?.split("| W")?.get(0).toString()
|
||||||
|
|
||||||
|
val isDubbed = canonicalTitle.contains("Dub")
|
||||||
|
val episodeNodes = document.select(".tab-content .nav-item > a")
|
||||||
|
|
||||||
|
val episodes = ArrayList<AnimeEpisode>(episodeNodes?.map {
|
||||||
|
AnimeEpisode(it.attr("href"))
|
||||||
|
}
|
||||||
|
?: ArrayList<AnimeEpisode>())
|
||||||
|
val statusElem = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(2)")
|
||||||
|
val status = when (statusElem?.text()?.replace("Status:", "")?.trim()) {
|
||||||
|
"Ongoing" -> ShowStatus.Ongoing
|
||||||
|
"Completed" -> ShowStatus.Completed
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
val yearText = document.selectFirst("div.elements div.row > div:nth-child(2) > div.row-line:nth-child(4)")?.text()
|
||||||
|
val year = yearText?.replace("Date release:", "")?.trim()?.split("-")?.get(0)?.toIntOrNull()
|
||||||
|
|
||||||
|
val poster = document.selectFirst(".film-poster-img")?.attr("src")
|
||||||
|
val type = document.selectFirst("span.item.mr-1 > a")?.text()?.trim()
|
||||||
|
|
||||||
|
val synopsis = document.selectFirst(".description > p")?.text()?.trim()
|
||||||
|
val genre = document.select("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(5) > a").map { it?.text()?.trim().toString() }
|
||||||
|
|
||||||
|
return AnimeLoadResponse(
|
||||||
|
canonicalTitle,
|
||||||
|
japaneseTitle,
|
||||||
|
canonicalTitle,
|
||||||
|
"$mainUrl/anime/${slug}",
|
||||||
|
this.name,
|
||||||
|
getType(type ?: ""),
|
||||||
|
poster,
|
||||||
|
year,
|
||||||
|
if(isDubbed) episodes else null,
|
||||||
|
if(!isDubbed) episodes else null,
|
||||||
|
status,
|
||||||
|
synopsis,
|
||||||
|
ArrayList(genre),
|
||||||
|
ArrayList(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadLinks(
|
||||||
|
data: String,
|
||||||
|
isCasting: Boolean,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
): Boolean {
|
||||||
|
val response = khttp.get(data)
|
||||||
|
val servers = Jsoup.parse(response.text).select("#servers-list > ul > li").map {
|
||||||
|
mapOf(
|
||||||
|
"link" to it?.selectFirst("a")?.attr("data-embed"),
|
||||||
|
"title" to it?.selectFirst("span")?.text()?.trim()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (server in servers) {
|
||||||
|
WcoStream().getSafeUrl(server["link"].toString(), "")?.forEach {
|
||||||
|
callback.invoke(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +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.StreamTape
|
|
||||||
import com.lagradost.cloudstream3.utils.extractors.XStreamCdn
|
|
||||||
|
|
||||||
data class ExtractorLink(
|
data class ExtractorLink(
|
||||||
val source: String,
|
val source: String,
|
||||||
|
@ -54,10 +51,12 @@ fun getAndUnpack(string: String): String? {
|
||||||
val extractorApis: Array<ExtractorApi> = arrayOf(
|
val extractorApis: Array<ExtractorApi> = arrayOf(
|
||||||
//AllProvider(),
|
//AllProvider(),
|
||||||
Shiro(),
|
Shiro(),
|
||||||
|
WcoStream(),
|
||||||
Mp4Upload(),
|
Mp4Upload(),
|
||||||
StreamTape(),
|
StreamTape(),
|
||||||
MixDrop(),
|
MixDrop(),
|
||||||
XStreamCdn()
|
XStreamCdn(),
|
||||||
|
StreamSB(),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getExtractorApiFromName(name: String): ExtractorApi {
|
fun getExtractorApiFromName(name: String): ExtractorApi {
|
||||||
|
@ -80,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 {
|
||||||
|
|
|
@ -13,7 +13,6 @@ 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 ->
|
||||||
|
@ -30,8 +29,5 @@ class MixDrop : ExtractorApi() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
} catch (e: Exception) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,6 @@ 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 ->
|
||||||
|
@ -26,8 +25,5 @@ class Mp4Upload : ExtractorApi() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
} catch (e: Exception) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,7 +27,6 @@ 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 ->
|
||||||
|
@ -63,9 +62,6 @@ class MultiQuality : ExtractorApi() {
|
||||||
}
|
}
|
||||||
return extractedLinksList
|
return extractedLinksList
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,6 @@ 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("""" + '""", "")
|
||||||
|
@ -29,8 +28,6 @@ class StreamTape : ExtractorApi() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
}
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.lagradost.cloudstream3.utils.extractors
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
import com.lagradost.cloudstream3.mapper
|
||||||
|
|
||||||
|
class WcoStream : ExtractorApi() {
|
||||||
|
override val name: String = "WcoStream"
|
||||||
|
override val mainUrl: String = "https://vidstream.pro"
|
||||||
|
override val requiresReferer = false
|
||||||
|
|
||||||
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
|
val baseUrl = url.split("/e/")[0]
|
||||||
|
|
||||||
|
val html = khttp.get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text
|
||||||
|
val (Id) = "/e/(.*?)?domain".toRegex().find(url)!!.destructured
|
||||||
|
val (skey) = """skey\s=\s['\"](.*?)['\"];""".toRegex().find(html)!!.destructured
|
||||||
|
|
||||||
|
val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey"
|
||||||
|
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
|
||||||
|
|
||||||
|
val response = khttp.get(apiLink, headers = mapOf("Referer" to referrer)).text
|
||||||
|
|
||||||
|
data class Sources(
|
||||||
|
@JsonProperty("file") val file: String,
|
||||||
|
@JsonProperty("label") val label: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Media(
|
||||||
|
@JsonProperty("sources") val sources: List<Sources>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class WcoResponse(
|
||||||
|
@JsonProperty("success") val success: Boolean,
|
||||||
|
@JsonProperty("media") val media: Media
|
||||||
|
)
|
||||||
|
|
||||||
|
val mapped = response.let { mapper.readValue<WcoResponse>(it) }
|
||||||
|
val sources = mutableListOf<ExtractorLink>()
|
||||||
|
|
||||||
|
if (mapped.success) {
|
||||||
|
mapped.media.sources.forEach {
|
||||||
|
sources.add(
|
||||||
|
ExtractorLink(
|
||||||
|
name,
|
||||||
|
name + if (it.label != null) "- ${it.label}" else "",
|
||||||
|
it.file,
|
||||||
|
"",
|
||||||
|
Qualities.HD.value,
|
||||||
|
it.file.contains(".m3u8")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sources
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,6 @@ 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",
|
||||||
|
@ -63,9 +62,5 @@ class XStreamCdn : ExtractorApi() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extractedLinksList
|
return extractedLinksList
|
||||||
} catch (e: Exception) {
|
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue