refactor import subs

This commit is contained in:
Bnyro 2022-08-06 11:09:28 +02:00
parent 02bbe45d82
commit 0e9443fff6
5 changed files with 129 additions and 106 deletions

View File

@ -0,0 +1,7 @@
package com.github.libretube.obj
data class NewPipeSubscription(
val name: String,
val service_id: Int,
val url: String
)

View File

@ -0,0 +1,7 @@
package com.github.libretube.obj
data class NewPipeSubscriptions(
val app_version: String = "",
val app_version_int: Int = 0,
val subscriptions: List<NewPipeSubscription>? = null
)

View File

@ -21,6 +21,7 @@ import com.github.libretube.dialogs.CustomInstanceDialog
import com.github.libretube.dialogs.DeleteAccountDialog import com.github.libretube.dialogs.DeleteAccountDialog
import com.github.libretube.dialogs.LoginDialog import com.github.libretube.dialogs.LoginDialog
import com.github.libretube.dialogs.LogoutDialog import com.github.libretube.dialogs.LogoutDialog
import com.github.libretube.util.ImportHelper
import com.github.libretube.util.PermissionHelper import com.github.libretube.util.PermissionHelper
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import org.json.JSONObject import org.json.JSONObject
@ -34,80 +35,6 @@ import java.util.zip.ZipInputStream
class InstanceSettings : PreferenceFragmentCompat() { class InstanceSettings : PreferenceFragmentCompat() {
val TAG = "InstanceSettings" val TAG = "InstanceSettings"
companion object {
lateinit var getContent: ActivityResultLauncher<String>
}
override fun onCreate(savedInstanceState: Bundle?) {
getContent =
registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
if (uri != null) {
try {
// Open a specific media item using ParcelFileDescriptor.
val resolver: ContentResolver =
requireActivity()
.contentResolver
// "rw" for read-and-write;
// "rwt" for truncating or overwriting existing file contents.
// val readOnlyMode = "r"
// uri - I have got from onActivityResult
val type = resolver.getType(uri)
var inputStream: InputStream? = resolver.openInputStream(uri)
val channels = ArrayList<String>()
if (type == "application/json") {
val json = inputStream?.bufferedReader()?.readLines()?.get(0)
val jsonObject = JSONTokener(json).nextValue() as JSONObject
Log.e(TAG, jsonObject.getJSONArray("subscriptions").toString())
for (
i in 0 until jsonObject.getJSONArray("subscriptions")
.length()
) {
var url =
jsonObject.getJSONArray("subscriptions").getJSONObject(i)
.getString("url")
url = url.replace("https://www.youtube.com/channel/", "")
Log.e(TAG, url)
channels.add(url)
}
} else {
if (type == "application/zip") {
val zis = ZipInputStream(inputStream)
var entry: ZipEntry? = zis.nextEntry
while (entry != null) {
if (entry.name.endsWith(".csv")) {
inputStream = zis
break
}
entry = zis.nextEntry
}
}
inputStream?.bufferedReader()?.readLines()?.forEach {
if (it.isNotBlank()) {
val channelId = it.substringBefore(",")
if (channelId.length == 24) {
channels.add(channelId)
}
}
}
}
inputStream?.close()
subscribe(channels)
} catch (e: Exception) {
Log.e(TAG, e.toString())
Toast.makeText(
context,
R.string.error,
Toast.LENGTH_SHORT
).show()
}
}
}
super.onCreate(savedInstanceState)
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.instance_settings, rootKey) setPreferencesFromResource(R.xml.instance_settings, rootKey)
@ -210,8 +137,8 @@ class InstanceSettings : PreferenceFragmentCompat() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
val customInstances = PreferenceHelper.getCustomInstances() val customInstances = PreferenceHelper.getCustomInstances()
var instanceNames = arrayListOf<String>() val instanceNames = arrayListOf<String>()
var instanceValues = arrayListOf<String>() val instanceValues = arrayListOf<String>()
// fetch official public instances // fetch official public instances
@ -263,39 +190,10 @@ class InstanceSettings : PreferenceFragmentCompat() {
// check StorageAccess // check StorageAccess
val accessGranted = val accessGranted =
PermissionHelper.isStoragePermissionGranted(activity as AppCompatActivity) PermissionHelper.isStoragePermissionGranted(activity as AppCompatActivity)
if (accessGranted) getContent.launch("*/*") if (accessGranted) ImportHelper(requireActivity() as AppCompatActivity).importSubscriptions()
else PermissionHelper.requestReadWrite(activity as AppCompatActivity) else PermissionHelper.requestReadWrite(activity as AppCompatActivity)
} else { } else {
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
} }
} }
private fun subscribe(channels: List<String>) {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val token = PreferenceHelper.getToken()
RetrofitInstance.authApi.importSubscriptions(
false,
token,
channels
)
} catch (e: IOException) {
Log.e(TAG, "IOException, you might not have internet connection")
return@launchWhenCreated
} catch (e: HttpException) {
Log.e(TAG, "HttpException, unexpected response$e")
return@launchWhenCreated
}
if (response.message == "ok") {
Toast.makeText(
context,
R.string.importsuccess,
Toast.LENGTH_SHORT
).show()
}
}
}
run()
}
} }

View File

@ -0,0 +1,93 @@
package com.github.libretube.util
import android.net.Uri
import android.util.Log
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.libretube.R
import com.github.libretube.obj.NewPipeSubscriptions
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
class ImportHelper(
private val activity: AppCompatActivity
) {
private val TAG = "ImportHelper"
fun importSubscriptions() {
getContent.launch("*/*")
}
val getContent =
activity.registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
if (uri != null) {
try {
val type = activity.contentResolver.getType(uri)
var inputStream: InputStream? = activity.contentResolver.openInputStream(uri)
var channels = ArrayList<String>()
if (type == "application/json") {
val mapper = ObjectMapper()
val json = readTextFromUri(uri)
val subscriptions = mapper.readValue(json, NewPipeSubscriptions::class.java)
channels = subscriptions.subscriptions?.map {
it.url.replace("https://www.youtube.com/channel/", "")
} as ArrayList<String>
} else if (type == "application/zip") {
val zis = ZipInputStream(inputStream)
var entry: ZipEntry? = zis.nextEntry
while (entry != null) {
if (entry.name.endsWith(".csv")) {
inputStream = zis
break
}
entry = zis.nextEntry
}
}
inputStream?.bufferedReader()?.readLines()?.forEach {
if (it.isNotBlank()) {
val channelId = it.substringBefore(",")
if (channelId.length == 24) {
channels.add(channelId)
}
}
}
inputStream?.close()
CoroutineScope(Dispatchers.IO).launch {
SubscriptionHelper.importSubscriptions(channels)
}
} catch (e: Exception) {
Log.e(TAG, e.toString())
Toast.makeText(
activity,
R.string.error,
Toast.LENGTH_SHORT
).show()
}
}
}
private fun readTextFromUri(uri: Uri): String {
val stringBuilder = StringBuilder()
activity.contentResolver.openInputStream(uri)?.use { inputStream ->
BufferedReader(InputStreamReader(inputStream)).use { reader ->
var line: String? = reader.readLine()
while (line != null) {
stringBuilder.append(line)
line = reader.readLine()
}
}
}
return stringBuilder.toString()
}
}

View File

@ -65,6 +65,24 @@ object SubscriptionHelper {
} }
} }
suspend fun importSubscriptions(channels: List<String>) {
if (PreferenceHelper.getToken() != "") {
val response = try {
val token = PreferenceHelper.getToken()
RetrofitInstance.authApi.importSubscriptions(
false,
token,
channels
)
} catch (e: Exception) {
e.printStackTrace()
}
} else {
val newChannels = PreferenceHelper.getLocalSubscriptions().toMutableList() + channels
PreferenceHelper.setLocalSubscriptions(newChannels)
}
}
fun getFormattedLocalSubscriptions(): String { fun getFormattedLocalSubscriptions(): String {
return PreferenceHelper.getLocalSubscriptions().joinToString(",") return PreferenceHelper.getLocalSubscriptions().joinToString(",")
} }