From 6688e7a5deb82838015815aaa2b292439c4ce2bf Mon Sep 17 00:00:00 2001 From: rimthekid Date: Thu, 31 Mar 2022 10:34:19 -0700 Subject: [PATCH] import subscription --- app/build.gradle | 4 +- app/release/output-metadata.json | 38 +++--- app/src/main/AndroidManifest.xml | 1 + .../java/com/github/libretube/MainActivity.kt | 6 + .../java/com/github/libretube/PipedApi.kt | 5 + .../com/github/libretube/SearchFragment.kt | 4 + .../java/com/github/libretube/Settings.kt | 110 +++++++++++------- app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/settings.xml | 2 +- 9 files changed, 105 insertions(+), 66 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 17038106f..298d93f81 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId 'com.github.libretube' minSdk 21 targetSdk 31 - versionCode 6 - versionName '0.2.4' + versionCode 7 + versionName '0.2.5' multiDexEnabled true testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' resValue "string", "app_name", "LibreTube" diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 6c783c252..135a379d0 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -16,23 +16,10 @@ } ], "attributes": [], - "versionCode": 6, - "versionName": "0.2.4", + "versionCode": 7, + "versionName": "0.2.5", "outputFile": "app-x86_64-release.apk" }, - { - "type": "ONE_OF_MANY", - "filters": [ - { - "filterType": "ABI", - "value": "arm64-v8a" - } - ], - "attributes": [], - "versionCode": 6, - "versionName": "0.2.4", - "outputFile": "app-arm64-v8a-release.apk" - }, { "type": "ONE_OF_MANY", "filters": [ @@ -42,10 +29,23 @@ } ], "attributes": [], - "versionCode": 6, - "versionName": "0.2.4", + "versionCode": 7, + "versionName": "0.2.5", "outputFile": "app-x86-release.apk" }, + { + "type": "ONE_OF_MANY", + "filters": [ + { + "filterType": "ABI", + "value": "arm64-v8a" + } + ], + "attributes": [], + "versionCode": 7, + "versionName": "0.2.5", + "outputFile": "app-arm64-v8a-release.apk" + }, { "type": "ONE_OF_MANY", "filters": [ @@ -55,8 +55,8 @@ } ], "attributes": [], - "versionCode": 6, - "versionName": "0.2.4", + "versionCode": 7, + "versionName": "0.2.5", "outputFile": "app-armeabi-v7a-release.apk" } ], diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1fe7b6b19..31c00cbde 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) + "L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + "D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) + } requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT bottomNavigationView = findViewById(R.id.bottomNav) diff --git a/app/src/main/java/com/github/libretube/PipedApi.kt b/app/src/main/java/com/github/libretube/PipedApi.kt index 600cfec40..f0d2bb31c 100644 --- a/app/src/main/java/com/github/libretube/PipedApi.kt +++ b/app/src/main/java/com/github/libretube/PipedApi.kt @@ -52,8 +52,13 @@ interface PipedApi { @POST("unsubscribe") suspend fun unsubscribe(@Header("Authorization") token: String, @Body subscribe: Subscribe): Message + @POST("import") + suspend fun importSubscriptions(@Header("Authorization") token: String, @Body channels: List): Message + //only for fetching servers list @GET suspend fun getInstances(@Url url: String): List + + } \ No newline at end of file diff --git a/app/src/main/java/com/github/libretube/SearchFragment.kt b/app/src/main/java/com/github/libretube/SearchFragment.kt index 4dd09676f..5bafb6d9b 100644 --- a/app/src/main/java/com/github/libretube/SearchFragment.kt +++ b/app/src/main/java/com/github/libretube/SearchFragment.kt @@ -125,4 +125,8 @@ class SearchFragment : Fragment() { requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) } + override fun onStop() { + super.onStop() + hideKeyboard() + } } diff --git a/app/src/main/java/com/github/libretube/Settings.kt b/app/src/main/java/com/github/libretube/Settings.kt index 85c729898..b901d8d53 100644 --- a/app/src/main/java/com/github/libretube/Settings.kt +++ b/app/src/main/java/com/github/libretube/Settings.kt @@ -1,13 +1,12 @@ package com.github.libretube import android.Manifest -import android.content.ContentValues.TAG +import android.content.ContentResolver import android.content.Context import android.content.pm.PackageManager import android.net.Uri import android.os.Build import android.os.Bundle -import android.os.Environment import android.text.TextUtils import android.util.Log import android.widget.Toast @@ -15,67 +14,83 @@ import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatDelegate import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.preference.ListPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat -import androidx.preference.SwitchPreferenceCompat import com.blankj.utilcode.util.UriUtils -import com.github.libretube.obj.Subscribe import retrofit2.HttpException -import java.io.ByteArrayOutputStream -import java.io.IOException -import java.io.InputStream +import java.io.* import java.util.zip.ZipFile + class Settings : PreferenceFragmentCompat() { val TAG = "Settings" companion object { lateinit var getContent: ActivityResultLauncher } - override fun onCreate(savedInstanceState: Bundle?) { getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? -> if (uri != null) { try{ - Log.d(TAG,UriUtils.uri2File(uri).toString()) - val file = UriUtils.uri2File(uri) - var inputStream: InputStream? = null - if (file.extension == "zip") { - var zipfile = ZipFile(file) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - var zipentry = - zipfile.getEntry("Takeout/YouTube and YouTube Music/subscriptions/subscriptions.csv") + // Open a specific media item using ParcelFileDescriptor. + val resolver: ContentResolver = + requireActivity() + .contentResolver - inputStream = zipfile.getInputStream(zipentry) - }else if(file.extension == "csv"){ - inputStream = file.inputStream() - } - val baos = ByteArrayOutputStream() - - inputStream?.use { it.copyTo(baos) } - - var subscriptions = baos.toByteArray().decodeToString() - - var subscribedCount = 0 - - for (text in subscriptions.lines()) { - if (text.take(24) != "Channel Id,Channel Url,C" && text.take(24).isNotEmpty()) { - subscribe(text.take(24)) - subscribedCount++ - Log.d(TAG, "subscribed: " + text + " total: " + subscribedCount) + // "rw" for read-and-write; + // "rwt" for truncating or overwriting existing file contents. + val readOnlyMode = "r" + // uri - I have got from onActivityResult + //uri = data.getData(); + val parcelFile = resolver.openFileDescriptor(uri, readOnlyMode) + val fileReader = FileReader(parcelFile!!.fileDescriptor) + val reader = BufferedReader(fileReader) + var line: String? + while (reader.readLine().also { line = it } != null) { + Log.d(TAG,reader.readLine()) } - } + reader.close() + fileReader.close() + }else{ + Log.d(TAG,UriUtils.uri2File(uri).toString()) + val file = UriUtils.uri2File(uri) + var inputStream: InputStream? = null + if (file.extension == "zip") { + var zipfile = ZipFile(file) - Toast.makeText( - context, - "Subscribed to " + subscribedCount + " channels.", - Toast.LENGTH_SHORT - ).show() + var zipentry = + zipfile.getEntry("Takeout/YouTube and YouTube Music/subscriptions/subscriptions.csv") + + inputStream = zipfile.getInputStream(zipentry) + }else if(file.extension == "csv"){ + inputStream = file.inputStream() + } + val baos = ByteArrayOutputStream() + + inputStream?.use { it.copyTo(baos) } + + var subscriptions = baos.toByteArray().decodeToString() + var channels: MutableList = emptyList().toMutableList() + var subscribedCount = 0 + for (text in subscriptions.lines().subList(1,subscriptions.lines().size)) { + if (text.replace(" ","") != "") { + val channel = text.split(",")[0] + channels.add(channel) + subscribedCount++ + Log.d(TAG, "subscribed: " + text + " total: " + subscribedCount) + } + } + subscribe(channels) + } }catch (e: Exception){ + Log.e(TAG,e.toString()) Toast.makeText( context, R.string.error, @@ -121,7 +136,9 @@ class Settings : PreferenceFragmentCompat() { //check StorageAccess if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { Log.d("myz", "" + Build.VERSION.SDK_INT) - if (!Environment.isExternalStorageManager()) { + if (ContextCompat.checkSelfPermission(this.requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED + ) { ActivityCompat.requestPermissions( this.requireActivity(), arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE, @@ -218,15 +235,12 @@ class Settings : PreferenceFragmentCompat() { } - private fun subscribe(channel_id: String) { + private fun subscribe(channels: List) { fun run() { lifecycleScope.launchWhenCreated { val response = try { val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) - RetrofitInstance.api.subscribe( - sharedPref?.getString("token", "")!!, - Subscribe(channel_id) - ) + RetrofitInstance.api.importSubscriptions(sharedPref?.getString("token", "")!!,channels) } catch (e: IOException) { Log.e(TAG, "IOException, you might not have internet connection") return@launchWhenCreated @@ -234,9 +248,17 @@ class Settings : PreferenceFragmentCompat() { Log.e(TAG, "HttpException, unexpected response$e") return@launchWhenCreated } + if(response.message == "ok"){ + Toast.makeText( + context, + R.string.importsuccess, + Toast.LENGTH_SHORT + ).show() + } } } run() } } + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 00a1e6b57..131e9c696 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,6 +23,7 @@ Choose a region Login/Register Please Login or Register from the settings to show your Subscriptions! + Subscribed successfully! Subscribe to some channels first! Can\'t Download this stream! Download is completed! diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index efcb289e0..98495f0af 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -59,7 +59,7 @@ app:key="grid" app:entries="@array/grid" app:entryValues="@array/grid" - app:defaultValue="" + app:defaultValue="@integer/grid_items" android:icon="@drawable/ic_column" app:useSimpleSummaryProvider="true" />