forked from recloudstream/cloudstream
Added loading repositories from url
This commit is contained in:
parent
8c0e07decb
commit
34660bcd48
8 changed files with 68 additions and 23 deletions
|
@ -178,6 +178,7 @@
|
||||||
<data android:scheme="https" android:host="aniflix.pro" 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="kimcartoon.li" android:pathPrefix="/"/>
|
||||||
<data android:scheme="https" android:host="xcine.me" android:pathPrefix="/"/>
|
<data android:scheme="https" android:host="xcine.me" android:pathPrefix="/"/>
|
||||||
|
<data android:scheme="https" android:host="cs.repo" android:pathPrefix="/"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
|
@ -10,6 +10,7 @@ import android.view.KeyEvent
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
@ -79,6 +80,9 @@ import java.io.File
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||||
|
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
|
||||||
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
|
|
||||||
|
|
||||||
const val VLC_PACKAGE = "org.videolan.vlc"
|
const val VLC_PACKAGE = "org.videolan.vlc"
|
||||||
|
@ -320,7 +324,26 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
val str = intent.dataString
|
val str = intent.dataString
|
||||||
loadCache()
|
loadCache()
|
||||||
if (str != null) {
|
if (str != null) {
|
||||||
if (str.contains(appString)) {
|
if (str.startsWith("https://cs.repo")) {
|
||||||
|
val realUrl = "https://" + str.substringAfter("?")
|
||||||
|
println("Repository url: $realUrl")
|
||||||
|
ioSafe {
|
||||||
|
val repo = RepositoryManager.parseRepository(realUrl) ?: return@ioSafe
|
||||||
|
RepositoryManager.addRepository(
|
||||||
|
RepositoryData(
|
||||||
|
repo.name,
|
||||||
|
realUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
|
main {
|
||||||
|
showToast(
|
||||||
|
this,
|
||||||
|
this.getString(R.string.player_loaded_subtitles, repo.name),
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (str.contains(appString)) {
|
||||||
for (api in OAuth2Apis) {
|
for (api in OAuth2Apis) {
|
||||||
if (str.contains("/${api.redirectUrl}")) {
|
if (str.contains("/${api.redirectUrl}")) {
|
||||||
ioSafe {
|
ioSafe {
|
||||||
|
|
|
@ -85,7 +85,7 @@ object PluginManager {
|
||||||
var loadedLocalPlugins = false
|
var loadedLocalPlugins = false
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
|
||||||
fun maybeLoadPlugin(context: Context, file: File) {
|
private fun maybeLoadPlugin(context: Context, file: File) {
|
||||||
val name = file.name
|
val name = file.name
|
||||||
if (file.extension == "zip" || file.extension == "cs3") {
|
if (file.extension == "zip" || file.extension == "cs3") {
|
||||||
loadPlugin(context, file, PluginData(name, null, false, file.absolutePath))
|
loadPlugin(context, file, PluginData(name, null, false, file.absolutePath))
|
||||||
|
|
|
@ -44,19 +44,19 @@ data class SitePlugin(
|
||||||
object RepositoryManager {
|
object RepositoryManager {
|
||||||
const val ONLINE_PLUGINS_FOLDER = "Extensions"
|
const val ONLINE_PLUGINS_FOLDER = "Extensions"
|
||||||
|
|
||||||
private suspend fun parseRepository(url: String): Repository? {
|
suspend fun parseRepository(url: String): Repository? {
|
||||||
return suspendSafeApiCall {
|
return suspendSafeApiCall {
|
||||||
// Take manifestVersion and such into account later
|
// Take manifestVersion and such into account later
|
||||||
app.get(url).parsedSafe()
|
app.get(url).parsedSafe()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun parsePlugins(pluginUrls: String): ArrayList<SitePlugin>? {
|
private suspend fun parsePlugins(pluginUrls: String): List<SitePlugin> {
|
||||||
// Take manifestVersion and such into account later
|
// Take manifestVersion and such into account later
|
||||||
val response = app.get(pluginUrls)
|
val response = app.get(pluginUrls)
|
||||||
// Normal parsed function not working?
|
// Normal parsed function not working?
|
||||||
// return response.parsedSafe()
|
// return response.parsedSafe()
|
||||||
return tryParseJson<ArrayList<SitePlugin>>(response.text)
|
return tryParseJson<Array<SitePlugin>>(response.text)?.toList() ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getRepoPlugins(repositoryUrl: String): List<SitePlugin>? {
|
suspend fun getRepoPlugins(repositoryUrl: String): List<SitePlugin>? {
|
||||||
|
@ -85,10 +85,21 @@ object RepositoryManager {
|
||||||
// Don't want to read before we write in another thread
|
// Don't want to read before we write in another thread
|
||||||
private val repoLock = Mutex()
|
private val repoLock = Mutex()
|
||||||
suspend fun addRepository(repository: RepositoryData) {
|
suspend fun addRepository(repository: RepositoryData) {
|
||||||
repoLock.withLock {
|
repoLock.withLock {
|
||||||
val currentRepos = getKey<List<RepositoryData>>(REPOSITORIES_KEY) ?: emptyList()
|
val currentRepos = getKey<Array<RepositoryData>>(REPOSITORIES_KEY) ?: emptyArray()
|
||||||
setKey(REPOSITORIES_KEY, currentRepos + repository)
|
// No duplicates
|
||||||
}
|
if (currentRepos.any { it.url == repository.url }) return
|
||||||
|
setKey(REPOSITORIES_KEY, currentRepos + repository)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun removeRepository(repository: RepositoryData) {
|
||||||
|
repoLock.withLock {
|
||||||
|
val currentRepos = getKey<Array<RepositoryData>>(REPOSITORIES_KEY) ?: emptyArray()
|
||||||
|
// No duplicates
|
||||||
|
val newRepos = currentRepos.filter { it.url != repository.url }
|
||||||
|
setKey(REPOSITORIES_KEY, newRepos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun write(stream: InputStream, output: OutputStream) {
|
private fun write(stream: InputStream, output: OutputStream) {
|
||||||
|
|
|
@ -39,16 +39,23 @@ class ExtensionsFragment : Fragment() {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
context?.fixPaddingStatusbar(extensions_root)
|
context?.fixPaddingStatusbar(extensions_root)
|
||||||
|
|
||||||
observe(extensionViewModel.repositories) {
|
repo_recycler_view?.adapter = RepoAdapter(emptyArray(), {
|
||||||
// Kinda cheap to do this instead of updates
|
findNavController().navigate(
|
||||||
repo_recycler_view?.adapter = RepoAdapter(it) {
|
R.id.navigation_settings_extensions_to_navigation_settings_plugins,
|
||||||
findNavController().navigate(
|
Bundle().apply {
|
||||||
R.id.navigation_settings_extensions_to_navigation_settings_plugins,
|
putString(PLUGINS_BUNDLE_NAME, it.name)
|
||||||
Bundle().apply {
|
putString(PLUGINS_BUNDLE_URL, it.url)
|
||||||
putString(PLUGINS_BUNDLE_NAME, it.name)
|
})
|
||||||
putString(PLUGINS_BUNDLE_URL, it.url)
|
}, { repo ->
|
||||||
})
|
ioSafe {
|
||||||
|
RepositoryManager.removeRepository(repo)
|
||||||
|
extensionViewModel.loadRepositories()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
observe(extensionViewModel.repositories) {
|
||||||
|
(repo_recycler_view?.adapter as? RepoAdapter)?.repositories = it
|
||||||
|
(repo_recycler_view?.adapter as? RepoAdapter)?.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
add_repo_button?.setOnClickListener {
|
add_repo_button?.setOnClickListener {
|
||||||
|
|
|
@ -46,8 +46,6 @@ class PluginAdapter(
|
||||||
plugin: SitePlugin
|
plugin: SitePlugin
|
||||||
) {
|
) {
|
||||||
val isDownloaded = storedPlugins.any { it.url == plugin.url }
|
val isDownloaded = storedPlugins.any { it.url == plugin.url }
|
||||||
println("ISOWNLOADED $isDownloaded ${storedPlugins.map { it.url }} ||||| ${plugin.url}")
|
|
||||||
|
|
||||||
|
|
||||||
val drawableInt = if (isDownloaded)
|
val drawableInt = if (isDownloaded)
|
||||||
R.drawable.ic_baseline_delete_outline_24
|
R.drawable.ic_baseline_delete_outline_24
|
||||||
|
|
|
@ -43,7 +43,6 @@ class PluginsFragment : Fragment() {
|
||||||
|
|
||||||
ioSafe {
|
ioSafe {
|
||||||
val plugins = extensionViewModel.getPlugins(url)
|
val plugins = extensionViewModel.getPlugins(url)
|
||||||
println("GET PLUGINS $plugins")
|
|
||||||
main {
|
main {
|
||||||
repo_recycler_view?.adapter = PluginAdapter(plugins) { plugin, isDownloaded ->
|
repo_recycler_view?.adapter = PluginAdapter(plugins) { plugin, isDownloaded ->
|
||||||
ioSafe {
|
ioSafe {
|
||||||
|
|
|
@ -9,8 +9,9 @@ import com.lagradost.cloudstream3.ui.settings.AccountClickCallback
|
||||||
import kotlinx.android.synthetic.main.repository_item.view.*
|
import kotlinx.android.synthetic.main.repository_item.view.*
|
||||||
|
|
||||||
class RepoAdapter(
|
class RepoAdapter(
|
||||||
private val repositories: Array<RepositoryData>,
|
var repositories: Array<RepositoryData>,
|
||||||
val clickCallback: (RepositoryData) -> Unit
|
val clickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
||||||
|
val imageClickCallback: RepoAdapter.(RepositoryData) -> Unit
|
||||||
) :
|
) :
|
||||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
@ -36,6 +37,11 @@ class RepoAdapter(
|
||||||
fun bind(
|
fun bind(
|
||||||
repositoryData: RepositoryData
|
repositoryData: RepositoryData
|
||||||
) {
|
) {
|
||||||
|
itemView.action_button?.setImageResource(R.drawable.ic_baseline_delete_outline_24)
|
||||||
|
itemView.action_button?.setOnClickListener {
|
||||||
|
imageClickCallback(repositoryData)
|
||||||
|
}
|
||||||
|
|
||||||
itemView.setOnClickListener {
|
itemView.setOnClickListener {
|
||||||
clickCallback(repositoryData)
|
clickCallback(repositoryData)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue