mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Play with CloudStream, fixed #1335
This commit is contained in:
parent
738d56916f
commit
bec9a87eed
6 changed files with 284 additions and 210 deletions
|
@ -4,7 +4,7 @@
|
|||
package="com.lagradost.cloudstream3">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- I dont remember, probs has to do with downloads -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.INTERNET" /> <!-- unless you only use cs3 as a player for downloaded stuff, you need this -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Downloads -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Downloads on low api devices-->
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- some dependency needs this -->
|
||||
|
@ -53,13 +53,19 @@
|
|||
<data android:scheme="content" />
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- I dont think this label can be translated, but idk -->
|
||||
<intent-filter android:label="@string/play_with_app_name">
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:mimeType="*/*"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden|navigation"
|
||||
android:label="@string/app_name"
|
||||
android:resizeableActivity="true"
|
||||
android:supportsPictureInPicture="true">
|
||||
<intent-filter android:exported="true">
|
||||
|
@ -68,11 +74,15 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:exported="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:scheme="https" android:host="elifilms.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www23.estrenosdoramas.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="pelisplus.icu" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="pelisplushd.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="pelismart.com" android:pathPrefix="/"/>
|
||||
|
@ -84,15 +94,15 @@
|
|||
<data android:scheme="https" android:host="pelisflix.li" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="seriesflix.video" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="ihavenotv.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="lookmovie.io" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www.vmovee.watch" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="allmoviesforyou.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="vidembed.cc" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="membed.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="vf-film.me" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="vf-serie.org" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="french-stream.re" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="asianembed.io" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="asiaflix.app" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="eja.tv/" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="bflix.ru" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="fmovies.to" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="sflix.pro" android:pathPrefix="/"/>
|
||||
|
@ -104,39 +114,71 @@
|
|||
<data android:scheme="https" android:host="www.pinoy-hd.xyz" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="pinoymovies.es" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="trailers.to" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www.2embed.ru" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="2embed.org" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="dramasee.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="watchasian.sh" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="watchasian.cx" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="185.224.83.103" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="kdramahood.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="akwam.to" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="mycima.tv" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="cimanow.cc" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www.egy.best" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="faselhd.io" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="secretlink.xyz" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="hdm.to" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="theflix.to" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="streamingcommunity.best" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="altadefinizione.tienda" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="cb01.rip" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="filmpertutti.love" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www.tantifilm.nl" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="v2.apimdb.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="cb01.rip" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="altadefinizione.tienda" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="filmpertutti.love" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="hdmovie2.art" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="http://167.88.14.149" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="149.56.24.226" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="hdtoday.cc" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="openvids.io" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="94.103.82.88" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="146.19.24.137" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="v2.vidsrc.me" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="uakino.club" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="phimmoichill.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="rezka.ag" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="yomovies.plus" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www.wcostream.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="gogoanime.film" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="gogoanime.sk" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="allanime.site" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="animekisa.in" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="animeflick.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www3.animeflv.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="animefenix.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="animeflv.io" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="jkanime.net" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="tenshi.moe" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="wcostream.cc" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="animepahe.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="dreamsub.me" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="9anime.id" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www.animeworld.tv" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="zoro.to" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="bestdubbedanime.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="monoschinos2.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="www.mundodonghua.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="kawaiifu.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="neonime.watch" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="kuramanime.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="65.108.132.145" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="185.231.223.76" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="75.119.159.228" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="45.12.2.2" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="otakudesu.watch" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="animeindo.sbs" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="111.90.143.42" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="tocanime.co" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="olgply.com" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="aniflix.pro" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="kimcartoon.li" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="xcine.me" android:pathPrefix="/"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.lagradost.cloudstream3.ui.player
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
|
@ -35,6 +37,34 @@ class DownloadedPlayerActivity : AppCompatActivity() {
|
|||
finish()
|
||||
}
|
||||
|
||||
private fun playLink(url: String) {
|
||||
this.navigate(
|
||||
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
|
||||
LinkGenerator(
|
||||
listOf(
|
||||
url
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun playUri(uri: Uri) {
|
||||
val name = UniFile.fromUri(this, uri).name
|
||||
this.navigate(
|
||||
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
|
||||
DownloadFileGenerator(
|
||||
listOf(
|
||||
ExtractorUri(
|
||||
uri = uri,
|
||||
name = name ?: getString(R.string.downloaded_file)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Log.i(DTAG, "onCreate")
|
||||
|
||||
|
@ -45,69 +75,35 @@ class DownloadedPlayerActivity : AppCompatActivity() {
|
|||
setContentView(R.layout.empty_layout)
|
||||
|
||||
val data = intent.data
|
||||
if (data == null) {
|
||||
|
||||
if (intent?.action == Intent.ACTION_SEND) {
|
||||
val extraText = try { // I dont trust android
|
||||
intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
val cd = intent.clipData
|
||||
val item = if (cd != null && cd.itemCount > 0) cd.getItemAt(0) else null
|
||||
val url = item?.text?.toString()
|
||||
|
||||
// idk what I am doing, just hope any of these work
|
||||
if (item?.uri != null)
|
||||
playUri(item.uri)
|
||||
else if (url != null)
|
||||
playLink(url)
|
||||
else if (data != null)
|
||||
playUri(data)
|
||||
else if (extraText != null)
|
||||
playLink(extraText)
|
||||
else {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
} else if (data?.scheme == "content") {
|
||||
playUri(data)
|
||||
} else {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
if (data.scheme == "content") {
|
||||
val name = UniFile.fromUri(this, data).name
|
||||
this.navigate(
|
||||
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
|
||||
DownloadFileGenerator(
|
||||
listOf(
|
||||
ExtractorUri(
|
||||
uri = data,
|
||||
name = name ?: getString(R.string.downloaded_file)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// Legacy code, seems to work perfectly fine without it
|
||||
|
||||
// } else {
|
||||
// val uri = getUri(intent.data)
|
||||
// if (uri == null) {
|
||||
// finish()
|
||||
// return
|
||||
// }
|
||||
// val path = uri.path
|
||||
// // Because it doesn't get the path when it's downloaded, I have no idea
|
||||
// val realPath = if (File(
|
||||
// intent.data?.path?.removePrefix("/file") ?: "NONE"
|
||||
// ).exists()
|
||||
// ) intent.data?.path?.removePrefix("/file") else path
|
||||
//
|
||||
// if (realPath == null) {
|
||||
// finish()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// val name = try {
|
||||
// File(realPath).name
|
||||
// } catch (e: Exception) {
|
||||
// "NULL"
|
||||
// }
|
||||
//
|
||||
// val tryUri = try {
|
||||
// AppUtils.getVideoContentUri(this, realPath) ?: uri
|
||||
// } catch (e: Exception) {
|
||||
// logError(e)
|
||||
// uri
|
||||
// }
|
||||
//
|
||||
// setContentView(R.layout.empty_layout)
|
||||
// Log.i(DTAG, "navigating")
|
||||
//
|
||||
// //TODO add relative path for subs
|
||||
// this.navigate(
|
||||
// R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
|
||||
// DownloadFileGenerator(listOf(ExtractorUri(uri = tryUri, name = name)))
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -1,10 +1,7 @@
|
|||
package com.lagradost.cloudstream3.ui.player
|
||||
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.ExtractorUri
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||
import com.lagradost.cloudstream3.utils.*
|
||||
|
||||
class LinkGenerator(
|
||||
private val links: List<String>,
|
||||
|
@ -50,12 +47,13 @@ class LinkGenerator(
|
|||
if (!extract || !loadExtractor(link, referer) {
|
||||
callback(it to null)
|
||||
}) {
|
||||
|
||||
// if don't extract or if no extractor found simply return the link
|
||||
callback(
|
||||
ExtractorLink(
|
||||
"",
|
||||
link,
|
||||
link,
|
||||
unshortenLinkSafe(link), // unshorten because it might be a raw link
|
||||
referer ?: "",
|
||||
Qualities.Unknown.value, link.contains(".m3u") // TODO USE REAL PARSER
|
||||
) to null
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.lagradost.cloudstream3.TvType
|
|||
import com.lagradost.cloudstream3.USER_AGENT
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.extractors.*
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
||||
import kotlinx.coroutines.delay
|
||||
import org.jsoup.Jsoup
|
||||
|
@ -143,6 +144,17 @@ fun getAndUnpack(string: String): String {
|
|||
return JsUnpacker(packedText).unpack() ?: string
|
||||
}
|
||||
|
||||
suspend fun unshortenLinkSafe(url : String) : String {
|
||||
return try {
|
||||
if (ShortLink.isShortLink(url))
|
||||
ShortLink.unshorten(url)
|
||||
else url
|
||||
} catch (e: Exception) {
|
||||
logError(e)
|
||||
url
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load the appropriate extractor based on link, returns true if any extractor is loaded.
|
||||
* */
|
||||
|
@ -151,14 +163,17 @@ suspend fun loadExtractor(
|
|||
referer: String? = null,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
val currentUrl = unshortenLinkSafe(url)
|
||||
|
||||
for (extractor in extractorApis) {
|
||||
if (url.replace(schemaStripRegex, "")
|
||||
if (currentUrl.replace(schemaStripRegex, "")
|
||||
.startsWith(extractor.mainUrl.replace(schemaStripRegex, ""))
|
||||
) {
|
||||
extractor.getSafeUrl(url, referer)?.forEach(callback)
|
||||
extractor.getSafeUrl(currentUrl, referer)?.forEach(callback)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -166,9 +181,11 @@ suspend fun loadExtractor(
|
|||
url: String,
|
||||
referer: String? = null,
|
||||
): List<ExtractorLink> {
|
||||
val currentUrl = unshortenLinkSafe(url)
|
||||
|
||||
for (extractor in extractorApis) {
|
||||
if (url.startsWith(extractor.mainUrl)) {
|
||||
return extractor.getSafeUrl(url, referer) ?: emptyList()
|
||||
if (currentUrl.startsWith(extractor.mainUrl)) {
|
||||
return extractor.getSafeUrl(currentUrl, referer) ?: emptyList()
|
||||
}
|
||||
}
|
||||
return emptyList()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package com.lagradost.cloudstream3.utils
|
||||
|
||||
import android.util.Base64
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.base64Decode
|
||||
|
@ -8,163 +9,182 @@ import java.net.URLDecoder
|
|||
|
||||
//Code heavily based on unshortenit.py form kodiondemand /addon
|
||||
|
||||
private data class ShortUrl(
|
||||
val regex: Regex,
|
||||
val type: String,
|
||||
val function: suspend (String) -> String,
|
||||
) {
|
||||
constructor(regex: String, type: String, function: suspend (String) -> String) : this(
|
||||
Regex(regex),
|
||||
type,
|
||||
function
|
||||
)
|
||||
companion object {
|
||||
val adflyRegex = """adf\.ly|j\.gs|q\.gs|u\.bb|ay\.gy|atominik\.com|tinyium\.com|microify\.com|threadsphere\.bid|clearload\.bid|activetect\.net|swiftviz\.net|briskgram\.net|activetect\.net|stoodsef\.com|baymaleti\.net|thouth\.net|uclaut\.net|gloyah\.net|larati\.net|scuseami\.net"""
|
||||
val linkupRegex = """linkup\.pro|buckler.link"""
|
||||
val linksafeRegex = """linksafe\.cc"""
|
||||
val nuovoIndirizzoRegex = """mixdrop\.nuovoindirizzo\.com"""
|
||||
val nuovoLinkRegex = """nuovolink\.com"""
|
||||
val uprotRegex = """uprot\.net"""
|
||||
val davisonbarkerRegex = """davisonbarker\.pro|lowrihouston\.pro"""
|
||||
|
||||
val shortList = listOf(
|
||||
ShortUrl(adflyRegex,"adfly",::unshortenAdfly),
|
||||
ShortUrl(linkupRegex,"linkup",::unshortenLinkup),
|
||||
ShortUrl(linksafeRegex,"linksafe",::unshortenLinksafe),
|
||||
ShortUrl(nuovoIndirizzoRegex,"nuovoindirizzo",::unshortenNuovoIndirizzo),
|
||||
ShortUrl(nuovoLinkRegex,"nuovolink",::unshortenNuovoLink),
|
||||
ShortUrl(uprotRegex,"uprot",::unshortenUprot),
|
||||
ShortUrl(davisonbarkerRegex,"uprot",::unshortenDavisonbarker),
|
||||
object ShortLink {
|
||||
data class ShortUrl(
|
||||
val regex: Regex,
|
||||
val type: String,
|
||||
val function: suspend (String) -> String,
|
||||
) {
|
||||
constructor(regex: String, type: String, function: suspend (String) -> String) : this(
|
||||
Regex(regex),
|
||||
type,
|
||||
function
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class ShortLink{
|
||||
fun isShortLink(url : String) : Boolean{
|
||||
return ShortUrl.shortList.firstOrNull {
|
||||
it.regex.find(url) != null}!=null
|
||||
private val adflyRegex =
|
||||
"""adf\.ly|j\.gs|q\.gs|u\.bb|ay\.gy|atominik\.com|tinyium\.com|microify\.com|threadsphere\.bid|clearload\.bid|activetect\.net|swiftviz\.net|briskgram\.net|activetect\.net|stoodsef\.com|baymaleti\.net|thouth\.net|uclaut\.net|gloyah\.net|larati\.net|scuseami\.net"""
|
||||
private val linkupRegex = """linkup\.pro|buckler.link"""
|
||||
private val linksafeRegex = """linksafe\.cc"""
|
||||
private val nuovoIndirizzoRegex = """mixdrop\.nuovoindirizzo\.com"""
|
||||
private val nuovoLinkRegex = """nuovolink\.com"""
|
||||
private val uprotRegex = """uprot\.net"""
|
||||
private val davisonbarkerRegex = """davisonbarker\.pro|lowrihouston\.pro"""
|
||||
|
||||
private val shortList = listOf(
|
||||
ShortUrl(adflyRegex, "adfly", ::unshortenAdfly),
|
||||
ShortUrl(linkupRegex, "linkup", ::unshortenLinkup),
|
||||
ShortUrl(linksafeRegex, "linksafe", ::unshortenLinksafe),
|
||||
ShortUrl(nuovoIndirizzoRegex, "nuovoindirizzo", ::unshortenNuovoIndirizzo),
|
||||
ShortUrl(nuovoLinkRegex, "nuovolink", ::unshortenNuovoLink),
|
||||
ShortUrl(uprotRegex, "uprot", ::unshortenUprot),
|
||||
ShortUrl(davisonbarkerRegex, "uprot", ::unshortenDavisonbarker),
|
||||
)
|
||||
|
||||
fun isShortLink(url: String): Boolean {
|
||||
return shortList.any {
|
||||
it.regex.find(url) != null
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun unshorten(uri: String, type: String? = null): String {
|
||||
var currentUrl = uri
|
||||
|
||||
while (true) {
|
||||
val oldurl = currentUrl
|
||||
val domain = URI(currentUrl).host ?: throw IllegalArgumentException("No domain found in URI!")
|
||||
currentUrl = ShortUrl.shortList.firstOrNull {
|
||||
val domain =
|
||||
URI(currentUrl).host ?: throw IllegalArgumentException("No domain found in URI!")
|
||||
currentUrl = shortList.firstOrNull {
|
||||
it.regex.find(domain) != null || type == it.type
|
||||
}?.function?.let { it(currentUrl) } ?: break
|
||||
if (oldurl == currentUrl){
|
||||
if (oldurl == currentUrl) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return currentUrl
|
||||
}
|
||||
}
|
||||
suspend fun unshortenAdfly(uri: String): String{
|
||||
val html = app.get(uri).text
|
||||
val ysmm = Regex("""var ysmm =.*\;?""").find(html)!!.value
|
||||
|
||||
if (ysmm.isNotEmpty()){
|
||||
var left = ""
|
||||
var right = ""
|
||||
suspend fun unshortenAdfly(uri: String): String {
|
||||
val html = app.get(uri).text
|
||||
val ysmm = Regex("""var ysmm =.*;?""").find(html)!!.value
|
||||
|
||||
if (ysmm.isNotEmpty()) {
|
||||
var left = ""
|
||||
var right = ""
|
||||
|
||||
|
||||
for (c in ysmm.replace(Regex("""var ysmm \= \'|\'\;"""),"").chunked(2).dropLastWhile {it.length==1}) {
|
||||
left += c[0]
|
||||
right = c[1] + right
|
||||
for (c in ysmm.replace(Regex("""var ysmm = '|';"""), "").chunked(2)
|
||||
.dropLastWhile { it.length == 1 }) {
|
||||
left += c[0]
|
||||
right = c[1] + right
|
||||
}
|
||||
val encodedUri = (left + right).toMutableList()
|
||||
val numbers =
|
||||
encodedUri.mapIndexed { i, n -> Pair(i, n) }.filter { it.second.isDigit() }
|
||||
for (el in numbers.chunked(2).dropLastWhile { it.size == 1 }) {
|
||||
val xor = (el[0].second).code.xor(el[1].second.code)
|
||||
if (xor < 10) {
|
||||
encodedUri[el[0].first] = xor.digitToChar()
|
||||
}
|
||||
}
|
||||
val encodedbytearray = encodedUri.map { it.code.toByte() }.toByteArray()
|
||||
var decodedUri =
|
||||
Base64.decode(encodedbytearray, Base64.DEFAULT).decodeToString().dropLast(16)
|
||||
.drop(16)
|
||||
|
||||
if (Regex("""go\.php\?u=""").find(decodedUri) != null) {
|
||||
decodedUri =
|
||||
Base64.decode(decodedUri.replace(Regex("""(.*?)u="""), ""), Base64.DEFAULT)
|
||||
.decodeToString()
|
||||
}
|
||||
|
||||
return decodedUri
|
||||
} else {
|
||||
return uri
|
||||
}
|
||||
val encodedUri = (left + right).toMutableList()
|
||||
val numbers = encodedUri.mapIndexed{ i, n-> Pair(i,n)}.filter{it.second.isDigit()}
|
||||
for (el in numbers.chunked(2).dropLastWhile {it.size==1}){
|
||||
val xor = (el[0].second).code.xor(el[1].second.code)
|
||||
if (xor < 10){
|
||||
encodedUri[el[0].first] = xor.digitToChar()
|
||||
}
|
||||
|
||||
suspend fun unshortenLinkup(uri: String): String {
|
||||
var r: NiceResponse? = null
|
||||
var uri = uri
|
||||
when {
|
||||
uri.contains("/tv/") -> uri = uri.replace("/tv/", "/tva/")
|
||||
uri.contains("delta") -> uri = uri.replace("/delta/", "/adelta/")
|
||||
(uri.contains("/ga/") || uri.contains("/ga2/")) -> uri =
|
||||
base64Decode(uri.split('/').last()).trim()
|
||||
uri.contains("/speedx/") -> uri =
|
||||
uri.replace("http://linkup.pro/speedx", "http://speedvideo.net")
|
||||
else -> {
|
||||
r = app.get(uri, allowRedirects = true)
|
||||
uri = r.url
|
||||
val link =
|
||||
Regex("<iframe[^<>]*src=\\'([^'>]*)\\'[^<>]*>").find(r.text)?.value
|
||||
?: Regex("""action="(?:[^/]+.*?/[^/]+/([a-zA-Z0-9_]+))">""").find(r.text)?.value
|
||||
?: Regex("""href","((.|\\n)*?)"""").findAll(r.text)
|
||||
.elementAtOrNull(1)?.groupValues?.get(1)
|
||||
|
||||
if (link != null) {
|
||||
uri = link
|
||||
}
|
||||
}
|
||||
}
|
||||
val encodedbytearray = encodedUri.map { it.code.toByte() }.toByteArray()
|
||||
var decodedUri = Base64.decode(encodedbytearray,Base64.DEFAULT).decodeToString().dropLast(16).drop(16)
|
||||
|
||||
if (Regex("""go\.php\?u\=""").find(decodedUri) != null){
|
||||
decodedUri = Base64.decode(decodedUri.replace(Regex("""(.*?)u="""),""),Base64.DEFAULT).decodeToString()
|
||||
val short = Regex("""^https?://.*?(https?://.*)""").find(uri)?.value
|
||||
if (short != null) {
|
||||
uri = short
|
||||
}
|
||||
if (r == null) {
|
||||
r = app.get(
|
||||
uri,
|
||||
allowRedirects = false
|
||||
)
|
||||
if (r.headers["location"] != null) {
|
||||
uri = r.headers["location"].toString()
|
||||
}
|
||||
}
|
||||
if (uri.contains("snip.")) {
|
||||
if (uri.contains("out_generator")) {
|
||||
uri = Regex("url=(.*)\$").find(uri)!!.value
|
||||
} else if (uri.contains("/decode/")) {
|
||||
uri = app.get(uri, allowRedirects = true).url
|
||||
}
|
||||
}
|
||||
|
||||
return decodedUri
|
||||
}
|
||||
else {
|
||||
return uri
|
||||
}
|
||||
return uri
|
||||
}
|
||||
suspend fun unshortenLinkup(uri: String): String {
|
||||
var r: NiceResponse? = null
|
||||
var uri = uri
|
||||
when{
|
||||
uri.contains("/tv/") -> uri = uri.replace("/tv/", "/tva/")
|
||||
uri.contains("delta") -> uri = uri.replace("/delta/", "/adelta/")
|
||||
(uri.contains("/ga/") || uri.contains("/ga2/")) -> uri = base64Decode(uri.split('/').last()).trim()
|
||||
uri.contains("/speedx/") -> uri = uri.replace("http://linkup.pro/speedx", "http://speedvideo.net")
|
||||
else -> {
|
||||
r = app.get(uri, allowRedirects = true)
|
||||
uri = r.url
|
||||
val link =
|
||||
Regex("<iframe[^<>]*src=\\'([^'>]*)\\'[^<>]*>").find(r.text)?.value ?:
|
||||
Regex("""action="(?:[^/]+.*?/[^/]+/([a-zA-Z0-9_]+))">""").find(r.text)?.value ?:
|
||||
Regex("""href","((.|\\n)*?)"""").findAll(r.text).elementAtOrNull(1)?.groupValues?.get(1)
|
||||
|
||||
if (link!=null) {
|
||||
uri = link
|
||||
fun unshortenLinksafe(uri: String): String {
|
||||
return base64Decode(uri.split("?url=").last())
|
||||
}
|
||||
|
||||
suspend fun unshortenNuovoIndirizzo(uri: String): String {
|
||||
val soup = app.get(uri, allowRedirects = true)
|
||||
val header = soup.headers["refresh"]
|
||||
val link: String = if (header != null) {
|
||||
soup.headers["refresh"]!!.substringAfter("=")
|
||||
} else {
|
||||
"non trovato"
|
||||
}
|
||||
return link
|
||||
}
|
||||
|
||||
suspend fun unshortenNuovoLink(uri: String): String {
|
||||
return app.get(uri, allowRedirects = true).document.selectFirst("a")!!.attr("href")
|
||||
|
||||
}
|
||||
|
||||
suspend fun unshortenUprot(uri: String): String {
|
||||
val page = app.get(uri).text
|
||||
Regex("""<a[^>]+href="([^"]+)""").findAll(page)
|
||||
.map { it.value.replace("""<a href="""", "") }
|
||||
.toList().forEach { link ->
|
||||
if (link.contains("https://maxstream.video") || link.contains("https://uprot.net") && link != uri) {
|
||||
return link
|
||||
}
|
||||
}
|
||||
}
|
||||
return uri
|
||||
}
|
||||
|
||||
val short = Regex("""^https?://.*?(https?://.*)""").find(uri)?.value
|
||||
if (short!=null){
|
||||
uri = short
|
||||
fun unshortenDavisonbarker(uri: String): String {
|
||||
return URLDecoder.decode(uri.substringAfter("dest="))
|
||||
}
|
||||
if (r==null){
|
||||
r = app.get(
|
||||
uri,
|
||||
allowRedirects = false)
|
||||
if (r.headers["location"]!= null){
|
||||
uri = r.headers["location"].toString()
|
||||
}
|
||||
}
|
||||
if (uri.contains("snip.")) {
|
||||
if (uri.contains("out_generator")) {
|
||||
uri = Regex("url=(.*)\$").find(uri)!!.value
|
||||
}
|
||||
else if (uri.contains("/decode/")) {
|
||||
uri = app.get(uri, allowRedirects = true).url
|
||||
}
|
||||
}
|
||||
return uri
|
||||
}
|
||||
fun unshortenLinksafe(uri:String) : String {
|
||||
return base64Decode(uri.split("?url=").last())
|
||||
}
|
||||
suspend fun unshortenNuovoIndirizzo(uri:String) : String {
|
||||
val soup = app.get(uri, allowRedirects = true)
|
||||
val header = soup.headers["refresh"]
|
||||
val link : String= if (header != null) {
|
||||
soup.headers["refresh"]!!.substringAfter("=") }
|
||||
else{
|
||||
"non trovato"
|
||||
}
|
||||
return link
|
||||
}
|
||||
suspend fun unshortenNuovoLink(uri:String) : String {
|
||||
return app.get(uri, allowRedirects = true).document.selectFirst("a")!!.attr("href")
|
||||
|
||||
}
|
||||
suspend fun unshortenUprot(uri: String): String {
|
||||
val page = app.get(uri).text
|
||||
Regex("""<a[^>]+href="([^"]+)""").findAll(page).map { it.value.replace("""<a href="""","") }.toList().forEach { link ->
|
||||
if (link.contains("https://maxstream.video") || link.contains("https://uprot.net") && link != uri){
|
||||
return link
|
||||
}
|
||||
}
|
||||
return uri
|
||||
}
|
||||
fun unshortenDavisonbarker(uri: String): String {
|
||||
return URLDecoder.decode(uri.substringAfter("dest="))
|
||||
}
|
|
@ -92,6 +92,7 @@
|
|||
<string name="duration_format" formatted="true">%d min</string>
|
||||
|
||||
<string name="app_name">CloudStream</string>
|
||||
<string name="play_with_app_name">Play with CloudStream</string>
|
||||
<string name="title_home">Home</string>
|
||||
<string name="title_search">Search</string>
|
||||
<string name="title_downloads">Downloads</string>
|
||||
|
|
Loading…
Reference in a new issue